mirror of
https://github.com/querydsl/querydsl.git
synced 2026-06-13 21:01:01 +08:00
Merge pull request #1232 from querydsl/i1116-querydsl3
Add GroupBy.sortedSet and sortedMap
This commit is contained in:
commit
8e78280166
@ -24,7 +24,7 @@ import com.mysema.util.MathUtils;
|
||||
* @param <T>
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public class GAvg<T extends Number & Comparable<T>> extends AbstractGroupExpression<T, T> {
|
||||
public class GAvg<T extends Number> extends AbstractGroupExpression<T, T> {
|
||||
|
||||
private static final long serialVersionUID = 3518868612387641383L;
|
||||
|
||||
|
||||
@ -13,9 +13,7 @@
|
||||
*/
|
||||
package com.mysema.query.group;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
import com.mysema.commons.lang.Pair;
|
||||
|
||||
@ -23,7 +21,7 @@ import com.mysema.commons.lang.Pair;
|
||||
* @param <K>
|
||||
* @param <V>
|
||||
*/
|
||||
class GMap<K, V> extends AbstractGroupExpression<Pair<K, V>, Map<K, V>> {
|
||||
abstract class GMap<K, V, M extends Map<K,V>> extends AbstractGroupExpression<Pair<K, V>, M> {
|
||||
|
||||
private static final long serialVersionUID = 7106389414200843920L;
|
||||
|
||||
@ -31,11 +29,13 @@ class GMap<K, V> extends AbstractGroupExpression<Pair<K, V>, Map<K, V>> {
|
||||
super(Map.class, qpair);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GroupCollector<Pair<K,V>, Map<K, V>> createGroupCollector() {
|
||||
return new GroupCollector<Pair<K,V>, Map<K, V>>() {
|
||||
protected abstract M createMap();
|
||||
|
||||
private final Map<K, V> map = new LinkedHashMap<K, V>();
|
||||
@Override
|
||||
public GroupCollector<Pair<K,V>, M> createGroupCollector() {
|
||||
return new GroupCollector<Pair<K,V>, M>() {
|
||||
|
||||
private final M map = createMap();
|
||||
|
||||
@Override
|
||||
public void add(Pair<K,V> pair) {
|
||||
@ -43,13 +43,40 @@ class GMap<K, V> extends AbstractGroupExpression<Pair<K, V>, Map<K, V>> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<K, V> get() {
|
||||
public M get() {
|
||||
return map;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
public static <T, U> GMap<T, U, Map<T,U>> createLinked(QPair<T, U> expr) {
|
||||
return new GMap<T, U, Map<T, U>>(expr) {
|
||||
@Override
|
||||
protected Map<T, U> createMap() {
|
||||
return new LinkedHashMap<T, U>();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static <T extends Comparable<? super T>, U> GMap<T, U, SortedMap<T, U>> createSorted(QPair<T, U> expr) {
|
||||
return new GMap<T, U, SortedMap<T, U>>(expr) {
|
||||
@Override
|
||||
protected SortedMap<T, U> createMap() {
|
||||
return new TreeMap<T, U>();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static <T, U> GMap<T, U, SortedMap<T, U>> createSorted(QPair<T, U> expr, final Comparator<? super T> comparator) {
|
||||
return new GMap<T, U, SortedMap<T, U>>(expr) {
|
||||
@Override
|
||||
protected SortedMap<T, U> createMap() {
|
||||
return new TreeMap<T, U>(comparator);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static class Mixin<K, V, T, U, R extends Map<? super T, ? super U>> extends AbstractGroupExpression<Pair<K, V>, R> {
|
||||
|
||||
private static final long serialVersionUID = 1939989270493531116L;
|
||||
@ -118,4 +145,4 @@ class GMap<K, V> extends AbstractGroupExpression<Pair<K, V>, Map<K, V>> {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,7 +20,7 @@ import com.mysema.query.types.Expression;
|
||||
*
|
||||
* @param <T>
|
||||
*/
|
||||
class GMax<T extends Comparable<T>> extends AbstractGroupExpression<T, T> {
|
||||
class GMax<T extends Comparable<? super T>> extends AbstractGroupExpression<T, T> {
|
||||
|
||||
private static final long serialVersionUID = 3815394663181131511L;
|
||||
|
||||
|
||||
@ -20,7 +20,7 @@ import com.mysema.query.types.Expression;
|
||||
*
|
||||
* @param <T>
|
||||
*/
|
||||
class GMin<T extends Comparable<T>> extends AbstractGroupExpression<T, T> {
|
||||
class GMin<T extends Comparable<? super T>> extends AbstractGroupExpression<T, T> {
|
||||
|
||||
private static final long serialVersionUID = 8312168556148122576L;
|
||||
|
||||
|
||||
@ -13,8 +13,7 @@
|
||||
*/
|
||||
package com.mysema.query.group;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
import com.mysema.query.types.Expression;
|
||||
|
||||
@ -23,32 +22,62 @@ import com.mysema.query.types.Expression;
|
||||
*
|
||||
* @param <T>
|
||||
*/
|
||||
class GSet<T> extends AbstractGroupExpression<T, Set<T>> {
|
||||
|
||||
abstract class GSet<T, S extends Set<T>> extends AbstractGroupExpression<T, S> {
|
||||
|
||||
private static final long serialVersionUID = -1575808026237160843L;
|
||||
|
||||
public GSet(Expression<T> expr) {
|
||||
super(Set.class, expr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GroupCollector<T,Set<T>> createGroupCollector() {
|
||||
return new GroupCollector<T,Set<T>>() {
|
||||
protected abstract S createSet();
|
||||
|
||||
@Override
|
||||
public GroupCollector<T, S> createGroupCollector() {
|
||||
return new GroupCollector<T, S>() {
|
||||
|
||||
private final S set = createSet();
|
||||
|
||||
private final Set<T> set = new LinkedHashSet<T>();
|
||||
|
||||
@Override
|
||||
public void add(T o) {
|
||||
if (o != null) {
|
||||
set.add(o);
|
||||
}
|
||||
set.add(o);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<T> get() {
|
||||
public S get() {
|
||||
return set;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static <U> GSet<U, Set<U>> createLinked(Expression<U> expr) {
|
||||
return new GSet<U, Set<U>>(expr) {
|
||||
@Override
|
||||
protected Set<U> createSet() {
|
||||
return new LinkedHashSet<U>();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static <U extends Comparable<? super U>> GSet<U, SortedSet<U>> createSorted(Expression<U> expr) {
|
||||
return new GSet<U, SortedSet<U>>(expr) {
|
||||
@Override
|
||||
protected SortedSet<U> createSet() {
|
||||
return new TreeSet<U>();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static <U> GSet<U, SortedSet<U>> createSorted(Expression<U> expr, final Comparator<? super U> comparator) {
|
||||
return new GSet<U, SortedSet<U>>(expr) {
|
||||
@Override
|
||||
protected SortedSet<U> createSet() {
|
||||
return new TreeSet<U>(comparator);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@ import com.mysema.util.MathUtils;
|
||||
* @param <T>
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public class GSum<T extends Number & Comparable<T>> extends AbstractGroupExpression<T, T> {
|
||||
public class GSum<T extends Number> extends AbstractGroupExpression<T, T> {
|
||||
|
||||
private static final long serialVersionUID = 3518868612387641383L;
|
||||
|
||||
|
||||
@ -13,42 +13,39 @@
|
||||
*/
|
||||
package com.mysema.query.group;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
import com.mysema.query.types.Expression;
|
||||
|
||||
/**
|
||||
* A group of rows. Group is build according to GroupDefinitions.
|
||||
*
|
||||
*
|
||||
* @author sasa
|
||||
*
|
||||
*/
|
||||
public interface Group {
|
||||
|
||||
|
||||
/**
|
||||
* @return Groups elements as an array
|
||||
*/
|
||||
Object[] toArray();
|
||||
|
||||
|
||||
/**
|
||||
* Returns the value of the given group.
|
||||
*
|
||||
*
|
||||
* @param <T> Type of element in a single ResultSet row, i.e. type of {@code Expression<T>}
|
||||
* @param <R> Target type of this group, e.g. {@code List<T>}
|
||||
* @param coldef
|
||||
* @param coldef
|
||||
* @throws NoSuchElementException if group is undefined.
|
||||
* @throws ClassCastException if group is of different type
|
||||
* @return Value of given group definition in this group
|
||||
*/
|
||||
<T, R> R getGroup(GroupExpression<T, R> coldef);
|
||||
|
||||
|
||||
/**
|
||||
* Returns the value of the given single valued expression. This is the
|
||||
* first value of given column within this group of the ResultSet.
|
||||
*
|
||||
*
|
||||
* @param <T> Value type
|
||||
* @param expr Grouped expression
|
||||
* @throws NoSuchElementException if group is undefined.
|
||||
@ -56,10 +53,10 @@ public interface Group {
|
||||
* @return Value of given expression in this group
|
||||
*/
|
||||
<T> T getOne(Expression<T> expr);
|
||||
|
||||
|
||||
/**
|
||||
* Returns a Set of values in this group.
|
||||
*
|
||||
*
|
||||
* @param <T> Value type of Set
|
||||
* @param expr Grouped expression
|
||||
* @throws NoSuchElementException if group is undefined.
|
||||
@ -67,29 +64,53 @@ public interface Group {
|
||||
* @return Set of values in this group
|
||||
*/
|
||||
<T> Set<T> getSet(Expression<T> expr);
|
||||
|
||||
|
||||
/**
|
||||
* Returns a List of values in this group.
|
||||
*
|
||||
* Returns a SortedSet of values in this group.
|
||||
*
|
||||
* @param <T> Value type of Set
|
||||
* @param expr Grouped expression
|
||||
* @throws NoSuchElementException if group is undefined.
|
||||
* @throws ClassCastException if group is of different type (e.g. List)
|
||||
* @return Set of values in this group
|
||||
*/
|
||||
<T> SortedSet<T> getSortedSet(Expression<T> expr);
|
||||
|
||||
/**
|
||||
* Returns a List of values in this group.
|
||||
*
|
||||
* @param <T> Value type of List
|
||||
* @param expr Grouped expression
|
||||
* @throws NoSuchElementException if group is undefined.
|
||||
* @throws NoSuchElementException if group is undefined.
|
||||
* @throws ClassCastException if group is of different type (e.g. Set)
|
||||
* @return List of values in this group
|
||||
*/
|
||||
<T> List<T> getList(Expression<T> expr);
|
||||
|
||||
|
||||
/**
|
||||
* Returns a Map of values in this group
|
||||
*
|
||||
*
|
||||
* @param <K> Key type of result Map
|
||||
* @param <V> Value type of result Map
|
||||
* @param key Key expression
|
||||
* @param value Value expression
|
||||
* @throws NoSuchElementException if group is undefined.
|
||||
* @throws NoSuchElementException if group is undefined.
|
||||
* @throws ClassCastException if group is of different type (e.g. List)
|
||||
* @return Map of values in this group
|
||||
*/
|
||||
<K, V> Map<K, V> getMap(Expression<K> key, Expression<V> value);
|
||||
|
||||
|
||||
/**
|
||||
* Returns a SortedMap of values in this group
|
||||
*
|
||||
* @param <K> Key type of result Map
|
||||
* @param <V> Value type of result Map
|
||||
* @param key Key expression
|
||||
* @param value Value expression
|
||||
* @throws NoSuchElementException if group is undefined.
|
||||
* @throws ClassCastException if group is of different type (e.g. List)
|
||||
* @return Map of values in this group
|
||||
*/
|
||||
<K, V> SortedMap<K, V> getSortedMap(Expression<K> key, Expression<V> value);
|
||||
|
||||
}
|
||||
@ -13,9 +13,7 @@
|
||||
*/
|
||||
package com.mysema.query.group;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
|
||||
import com.mysema.commons.lang.Pair;
|
||||
@ -57,7 +55,7 @@ public final class GroupBy {
|
||||
* @param expression
|
||||
* @return
|
||||
*/
|
||||
public static <E extends Comparable<E>> AbstractGroupExpression<E, E> min(Expression<E> expression) {
|
||||
public static <E extends Comparable<? super E>> AbstractGroupExpression<E, E> min(Expression<E> expression) {
|
||||
return new GMin<E>(expression);
|
||||
}
|
||||
|
||||
@ -67,7 +65,7 @@ public final class GroupBy {
|
||||
* @param expression
|
||||
* @return
|
||||
*/
|
||||
public static <E extends Number & Comparable<E>> AbstractGroupExpression<E, E> sum(Expression<E> expression) {
|
||||
public static <E extends Number> AbstractGroupExpression<E, E> sum(Expression<E> expression) {
|
||||
return new GSum<E>(expression);
|
||||
}
|
||||
|
||||
@ -77,7 +75,7 @@ public final class GroupBy {
|
||||
* @param expression
|
||||
* @return
|
||||
*/
|
||||
public static <E extends Number & Comparable<E>> AbstractGroupExpression<E, E> avg(Expression<E> expression) {
|
||||
public static <E extends Number> AbstractGroupExpression<E, E> avg(Expression<E> expression) {
|
||||
return new GAvg<E>(expression);
|
||||
}
|
||||
|
||||
@ -87,7 +85,7 @@ public final class GroupBy {
|
||||
* @param expression
|
||||
* @return
|
||||
*/
|
||||
public static <E extends Comparable<E>> AbstractGroupExpression<E, E> max(Expression<E> expression) {
|
||||
public static <E extends Comparable<? super E>> AbstractGroupExpression<E, E> max(Expression<E> expression) {
|
||||
return new GMax<E>(expression);
|
||||
}
|
||||
|
||||
@ -106,21 +104,65 @@ public final class GroupBy {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new aggregating set expression
|
||||
* Create a new aggregating set expression using a backing LinkedHashSet
|
||||
*
|
||||
* @param expression
|
||||
* @return
|
||||
*/
|
||||
public static <E> AbstractGroupExpression<E, Set<E>> set(Expression<E> expression) {
|
||||
return new GSet<E>(expression);
|
||||
return GSet.createLinked(expression);
|
||||
}
|
||||
|
||||
public static <E, F> GroupExpression<E, Set<F>> set(GroupExpression<E, F> groupExpression) {
|
||||
return new MixinGroupExpression<E, F, Set<F>>(groupExpression, new GSet<F>(groupExpression));
|
||||
return new MixinGroupExpression<E, F, Set<F>>(groupExpression, GSet.createLinked(groupExpression));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new aggregating map expression
|
||||
* Create a new aggregating set expression using a backing TreeSet
|
||||
*
|
||||
* @param expression
|
||||
* @return
|
||||
*/
|
||||
public static <E extends Comparable<? super E>> AbstractGroupExpression<E, SortedSet<E>> sortedSet(Expression<E> expression) {
|
||||
return GSet.createSorted(expression);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new aggregating set expression using a backing TreeSet
|
||||
*
|
||||
* @param groupExpression
|
||||
* @return
|
||||
*/
|
||||
public static <E, F extends Comparable<? super F>> GroupExpression<E, SortedSet<F>> sortedSet(GroupExpression<E, F> groupExpression) {
|
||||
return new MixinGroupExpression<E, F, SortedSet<F>>(groupExpression, GSet.createSorted(groupExpression));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a new aggregating set expression using a backing TreeSet using the given comparator
|
||||
*
|
||||
* @param expression
|
||||
* @param comparator
|
||||
* @return
|
||||
*/
|
||||
public static <E> AbstractGroupExpression<E, SortedSet<E>> sortedSet(Expression<E> expression, Comparator<? super E> comparator) {
|
||||
return GSet.createSorted(expression, comparator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new aggregating set expression using a backing TreeSet using the given comparator
|
||||
*
|
||||
* @param groupExpression
|
||||
* @param comparator
|
||||
* @return
|
||||
*/
|
||||
public static <E, F> GroupExpression<E, SortedSet<F>> sortedSet(GroupExpression<E, F> groupExpression, Comparator<? super F> comparator) {
|
||||
return new MixinGroupExpression<E, F, SortedSet<F>>(groupExpression, GSet.createSorted(groupExpression, comparator));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a new aggregating map expression using a backing LinkedHashMap
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
@ -128,21 +170,135 @@ public final class GroupBy {
|
||||
*/
|
||||
@WithBridgeMethods(value=Expression.class,castRequired=true)
|
||||
public static <K, V> AbstractGroupExpression<Pair<K, V>,Map<K, V>> map(Expression<K> key, Expression<V> value) {
|
||||
return new GMap<K, V>(QPair.create(key, value));
|
||||
return GMap.createLinked(QPair.create(key, value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new aggregating map expression using a backing LinkedHashMap
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public static <K, V, T> AbstractGroupExpression<Pair<K, V>, Map<T, V>> map(GroupExpression<K, T> key, Expression<V> value) {
|
||||
return map(key, new GOne<V>(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new aggregating map expression using a backing LinkedHashMap
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public static <K, V, U> AbstractGroupExpression<Pair<K, V>, Map<K, U>> map(Expression<K> key, GroupExpression<V, U> value) {
|
||||
return map(new GOne<K>(key), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new aggregating map expression using a backing LinkedHashMap
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public static <K, V, T, U> AbstractGroupExpression<Pair<K, V>, Map<T, U>> map(GroupExpression<K, T> key, GroupExpression<V, U> value) {
|
||||
return new GMap.Mixin<K, V, T, U, Map<T, U>>(key, value, new GMap<T, U>(QPair.create(key, value)));
|
||||
return new GMap.Mixin<K, V, T, U, Map<T, U>>(key, value, GMap.createLinked(QPair.create(key, value)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new aggregating map expression using a backing TreeMap
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public static <K extends Comparable<? super K>, V> AbstractGroupExpression<Pair<K, V>, SortedMap<K, V>> sortedMap(Expression<K> key, Expression<V> value) {
|
||||
return GMap.createSorted(QPair.create(key, value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new aggregating map expression using a backing TreeMap
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public static <K extends Comparable<? super K>, V, T extends Comparable<? super T>> AbstractGroupExpression<Pair<K, V>, SortedMap<T, V>> sortedMap(GroupExpression<K, T> key, Expression<V> value) {
|
||||
return sortedMap(key, new GOne<V>(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new aggregating map expression using a backing TreeMap
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public static <K extends Comparable<? super K>, V, U> AbstractGroupExpression<Pair<K, V>, SortedMap<K, U>> sortedMap(Expression<K> key, GroupExpression<V, U> value) {
|
||||
return sortedMap(new GOne<K>(key), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new aggregating map expression using a backing TreeMap
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public static <K extends Comparable<? super K>, V, T extends Comparable<? super T>, U> AbstractGroupExpression<Pair<K, V>, SortedMap<T, U>> sortedMap(GroupExpression<K, T> key, GroupExpression<V, U> value) {
|
||||
return new GMap.Mixin<K, V, T, U, SortedMap<T, U>>(key, value, GMap.createSorted(QPair.create(key, value)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new aggregating map expression using a backing TreeMap using the given comparator
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
* @param comparator
|
||||
* @return
|
||||
*/
|
||||
public static <K, V> AbstractGroupExpression<Pair<K, V>, SortedMap<K, V>> sortedMap(Expression<K> key, Expression<V> value, Comparator<? super K> comparator) {
|
||||
return GMap.createSorted(QPair.create(key, value), comparator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new aggregating map expression using a backing TreeMap using the given comparator
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
* @param comparator
|
||||
* @return
|
||||
*/
|
||||
public static <K, V, T> AbstractGroupExpression<Pair<K, V>, SortedMap<T, V>> sortedMap(GroupExpression<K, T> key, Expression<V> value, Comparator<? super K> comparator) {
|
||||
return sortedMap(key, new GOne<V>(value), comparator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new aggregating map expression using a backing TreeMap using the given comparator
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
* @param comparator
|
||||
* @return
|
||||
*/
|
||||
public static <K, V, U> AbstractGroupExpression<Pair<K, V>, SortedMap<K, U>> sortedMap(Expression<K> key, GroupExpression<V, U> value, Comparator<? super U> comparator) {
|
||||
return sortedMap(new GOne<K>(key), value, comparator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new aggregating map expression using a backing TreeMap using the given comparator
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
* @param comparator
|
||||
* @return
|
||||
*/
|
||||
public static <K, V, T, U> AbstractGroupExpression<Pair<K, V>, SortedMap<T, U>> sortedMap(GroupExpression<K, T> key, GroupExpression<V, U> value, Comparator<? super T> comparator) {
|
||||
return new GMap.Mixin<K, V, T, U, SortedMap<T, U>>(key, value, GMap.createSorted(QPair.create(key, value), comparator));
|
||||
}
|
||||
|
||||
|
||||
private GroupBy() {}
|
||||
|
||||
}
|
||||
|
||||
@ -13,12 +13,7 @@
|
||||
*/
|
||||
package com.mysema.query.group;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
import com.mysema.query.types.Expression;
|
||||
import com.mysema.query.types.Operation;
|
||||
@ -104,6 +99,16 @@ class GroupImpl implements Group {
|
||||
throw new NoSuchElementException("GMap(" + key + ", " + value + ")");
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> SortedMap<K, V> getSortedMap(Expression<K> key, Expression<V> value) {
|
||||
for (QPair<?, ?> pair : maps) {
|
||||
if (pair.equals(key, value)) {
|
||||
return (SortedMap<K, V>) groupCollectorMap.get(pair).get();
|
||||
}
|
||||
}
|
||||
throw new NoSuchElementException("GMap(" + key + ", " + value + ")");
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getOne(Expression<T> expr) {
|
||||
return this.<T, T>get(expr);
|
||||
@ -114,6 +119,11 @@ class GroupImpl implements Group {
|
||||
return this.<T, Set<T>>get(expr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> SortedSet<T> getSortedSet(Expression<T> expr) {
|
||||
return this.<T, SortedSet<T>>get(expr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] toArray() {
|
||||
List<Object> arr = new ArrayList<Object>(groupCollectors.size());
|
||||
|
||||
@ -34,6 +34,17 @@ public abstract class AbstractGroupByTest {
|
||||
row(3, "post 3", 6, "comment 6")
|
||||
);
|
||||
|
||||
protected static final Projectable BASIC_RESULTS_UNORDERED = projectable(
|
||||
row(null, "null post", 8, "comment 8"),
|
||||
row(null, "null post", 7, "comment 7"),
|
||||
row(1, "post 1", 2, "comment 2"),
|
||||
row(1, "post 1", 1, "comment 1"),
|
||||
row(2, "post 2", 4, "comment 4"),
|
||||
row(1, "post 1", 3, "comment 3"),
|
||||
row(3, "post 3", 6, "comment 6"),
|
||||
row(2, "post 2", 5, "comment 5")
|
||||
);
|
||||
|
||||
protected static final Projectable MAP_RESULTS = projectable(
|
||||
row(null, "null post", pair(7, "comment 7")),
|
||||
row(null, "null post", pair(8, "comment 8")),
|
||||
|
||||
@ -14,23 +14,14 @@
|
||||
package com.mysema.query.group;
|
||||
|
||||
|
||||
import static com.mysema.query.group.GroupBy.groupBy;
|
||||
import static com.mysema.query.group.GroupBy.list;
|
||||
import static com.mysema.query.group.GroupBy.map;
|
||||
import static com.mysema.query.group.GroupBy.set;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static com.mysema.query.group.GroupBy.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.*;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.google.common.collect.Ordering;
|
||||
import com.mysema.commons.lang.Pair;
|
||||
import com.mysema.query.Tuple;
|
||||
import com.mysema.query.types.Projections;
|
||||
@ -40,14 +31,38 @@ public class GroupByMapTest extends AbstractGroupByTest {
|
||||
@Test
|
||||
public void Group_Order() {
|
||||
Map<Integer, Group> results = BASIC_RESULTS
|
||||
.transform(groupBy(postId).as(postName, set(commentId)));
|
||||
.transform(groupBy(postId).as(postName, set(commentId)));
|
||||
assertEquals(4, results.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Set_By_Sorted() {
|
||||
Map<Integer, Group> results = BASIC_RESULTS_UNORDERED
|
||||
.transform(groupBy(postId).as(postName, sortedSet(commentId)));
|
||||
|
||||
Group group = results.get(1);
|
||||
Iterator<Integer> it = group.getSet(commentId).iterator();
|
||||
assertEquals(1, it.next().intValue());
|
||||
assertEquals(2, it.next().intValue());
|
||||
assertEquals(3, it.next().intValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Set_By_Sorted_Reverse() {
|
||||
Map<Integer, Group> results = BASIC_RESULTS_UNORDERED
|
||||
.transform(groupBy(postId).as(postName, sortedSet(commentId, Ordering.natural().reverse())));
|
||||
|
||||
Group group = results.get(1);
|
||||
Iterator<Integer> it = group.getSet(commentId).iterator();
|
||||
assertEquals(3, it.next().intValue());
|
||||
assertEquals(2, it.next().intValue());
|
||||
assertEquals(1, it.next().intValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void First_Set_And_List() {
|
||||
Map<Integer, Group> results = BASIC_RESULTS.transform(
|
||||
groupBy(postId).as(postName, set(commentId), list(commentText)));
|
||||
groupBy(postId).as(postName, set(commentId), list(commentText)));
|
||||
|
||||
Group group = results.get(1);
|
||||
assertEquals(toInt(1), group.getOne(postId));
|
||||
@ -59,7 +74,7 @@ public class GroupByMapTest extends AbstractGroupByTest {
|
||||
@Test
|
||||
public void Group_By_Null() {
|
||||
Map<Integer, Group> results = BASIC_RESULTS.transform(
|
||||
groupBy(postId).as(postName, set(commentId), list(commentText)));
|
||||
groupBy(postId).as(postName, set(commentId), list(commentText)));
|
||||
|
||||
Group group = results.get(null);
|
||||
assertNull(group.getOne(postId));
|
||||
@ -72,7 +87,7 @@ public class GroupByMapTest extends AbstractGroupByTest {
|
||||
@Test(expected=NoSuchElementException.class)
|
||||
public void NoSuchElementException() {
|
||||
Map<Integer, Group> results = BASIC_RESULTS.transform(
|
||||
groupBy(postId).as(postName, set(commentId), list(commentText)));
|
||||
groupBy(postId).as(postName, set(commentId), list(commentText)));
|
||||
|
||||
Group group = results.get(1);
|
||||
group.getSet(qComment);
|
||||
@ -81,7 +96,7 @@ public class GroupByMapTest extends AbstractGroupByTest {
|
||||
@Test(expected=ClassCastException.class)
|
||||
public void ClassCastException() {
|
||||
Map<Integer, Group> results = BASIC_RESULTS.transform(
|
||||
groupBy(postId).as(postName, set(commentId), list(commentText)));
|
||||
groupBy(postId).as(postName, set(commentId), list(commentText)));
|
||||
|
||||
Group group = results.get(1);
|
||||
group.getList(commentId);
|
||||
@ -90,7 +105,7 @@ public class GroupByMapTest extends AbstractGroupByTest {
|
||||
@Test
|
||||
public void Map() {
|
||||
Map<Integer, Group> results = MAP_RESULTS.transform(
|
||||
groupBy(postId).as(postName, map(commentId, commentText)));
|
||||
groupBy(postId).as(postName, map(commentId, commentText)));
|
||||
|
||||
Group group = results.get(1);
|
||||
|
||||
@ -99,26 +114,53 @@ public class GroupByMapTest extends AbstractGroupByTest {
|
||||
assertEquals("comment 2", comments.get(2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Map_Sorted() {
|
||||
Map<Integer, Group> results = MAP_RESULTS.transform(
|
||||
groupBy(postId).as(postName, sortedMap(commentId, commentText)));
|
||||
|
||||
Group group = results.get(1);
|
||||
|
||||
Iterator<Map.Entry<Integer, String>> it = group.getMap(commentId, commentText).entrySet().iterator();
|
||||
assertEquals(1, it.next().getKey().intValue());
|
||||
assertEquals(2, it.next().getKey().intValue());
|
||||
assertEquals(3, it.next().getKey().intValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Map_Sorted_Reverse() {
|
||||
Map<Integer, Group> results = MAP_RESULTS.transform(
|
||||
groupBy(postId).as(postName, sortedMap(commentId, commentText, Ordering.natural().reverse())));
|
||||
|
||||
Group group = results.get(1);
|
||||
|
||||
Iterator<Map.Entry<Integer, String>> it = group.getMap(commentId, commentText).entrySet().iterator();
|
||||
assertEquals(3, it.next().getKey().intValue());
|
||||
assertEquals(2, it.next().getKey().intValue());
|
||||
assertEquals(1, it.next().getKey().intValue());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void Map2() {
|
||||
Map<Integer, Map<Integer, String>> results = MAP2_RESULTS.transform(
|
||||
groupBy(postId).as(map(commentId, commentText)));
|
||||
groupBy(postId).as(map(commentId, commentText)));
|
||||
|
||||
Map<Integer, String> comments = results.get(1);
|
||||
assertEquals(3, comments.size());
|
||||
assertEquals("comment 2", comments.get(2));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void Map3() {
|
||||
public void Map3() {
|
||||
Map<Integer, Map<Integer, Map<Integer, String>>> actual = MAP3_RESULTS.transform(
|
||||
groupBy(postId).as(map(postId, map(commentId, commentText))));
|
||||
|
||||
groupBy(postId).as(map(postId, map(commentId, commentText))));
|
||||
|
||||
Map<Integer, Map<Integer, Map<Integer, String>>> expected = new LinkedHashMap<Integer, Map<Integer, Map<Integer, String>>>();
|
||||
for (Iterator<Tuple> iterator = MAP3_RESULTS.iterate(); iterator.hasNext();) {
|
||||
Tuple tuple = iterator.next();
|
||||
Object[] array = tuple.toArray();
|
||||
|
||||
|
||||
Map<Integer, Map<Integer, String>> posts = expected.get(array[0]);
|
||||
if (posts == null) {
|
||||
posts = new LinkedHashMap<Integer, Map<Integer,String>>();
|
||||
@ -134,20 +176,20 @@ public class GroupByMapTest extends AbstractGroupByTest {
|
||||
}
|
||||
Pair<Integer, String> second = pair.getSecond();
|
||||
comments.put(second.getFirst(), second.getSecond());
|
||||
}
|
||||
}
|
||||
assertEquals(expected.toString(), actual.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Map4() {
|
||||
public void Map4() {
|
||||
Map<Integer, Map<Map<Integer, String>, String>> actual = MAP4_RESULTS.transform(
|
||||
groupBy(postId).as(map(map(postId, commentText), postName)));
|
||||
|
||||
groupBy(postId).as(map(map(postId, commentText), postName)));
|
||||
|
||||
Map<Integer, Map<Map<Integer, String>, String>> expected = new LinkedHashMap<Integer, Map<Map<Integer, String>, String>>();
|
||||
for (Iterator<Tuple> iterator = MAP4_RESULTS.iterate(); iterator.hasNext();) {
|
||||
Tuple tuple = iterator.next();
|
||||
Object[] array = tuple.toArray();
|
||||
|
||||
|
||||
Map<Map<Integer, String>, String> comments = expected.get(array[0]);
|
||||
if (comments == null) {
|
||||
comments = new LinkedHashMap<Map<Integer, String>, String>();
|
||||
@ -155,17 +197,17 @@ public class GroupByMapTest extends AbstractGroupByTest {
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
Pair<Pair<Integer, String>, String> pair = (Pair<Pair<Integer, String>, String>) array[1];
|
||||
Pair<Integer, String> first = pair.getFirst();
|
||||
Pair<Integer, String> first = pair.getFirst();
|
||||
Map<Integer, String> posts = Collections.singletonMap(first.getFirst(), first.getSecond());
|
||||
comments.put(posts, pair.getSecond());
|
||||
}
|
||||
}
|
||||
assertEquals(expected.toString(), actual.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Array_Access() {
|
||||
Map<Integer, Group> results = BASIC_RESULTS.transform(
|
||||
groupBy(postId).as(postName, set(commentId), list(commentText)));
|
||||
groupBy(postId).as(postName, set(commentId), list(commentText)));
|
||||
|
||||
Group group = results.get(1);
|
||||
Object[] array = group.toArray();
|
||||
@ -224,8 +266,8 @@ public class GroupByMapTest extends AbstractGroupByTest {
|
||||
@Test
|
||||
public void OneToOneToMany_Projection() {
|
||||
Map<String, User> results = USERS_W_LATEST_POST_AND_COMMENTS.transform(
|
||||
groupBy(userName).as(Projections.constructor(User.class, userName,
|
||||
Projections.constructor(Post.class, postId, postName, set(qComment)))));
|
||||
groupBy(userName).as(Projections.constructor(User.class, userName,
|
||||
Projections.constructor(Post.class, postId, postName, set(qComment)))));
|
||||
|
||||
assertEquals(2, results.size());
|
||||
|
||||
@ -239,8 +281,8 @@ public class GroupByMapTest extends AbstractGroupByTest {
|
||||
@Test
|
||||
public void OneToOneToMany_Projection_As_Bean() {
|
||||
Map<String, User> results = USERS_W_LATEST_POST_AND_COMMENTS.transform(
|
||||
groupBy(userName).as(Projections.bean(User.class, userName,
|
||||
Projections.bean(Post.class, postId, postName, set(qComment).as("comments")).as("latestPost"))));
|
||||
groupBy(userName).as(Projections.bean(User.class, userName,
|
||||
Projections.bean(Post.class, postId, postName, set(qComment).as("comments")).as("latestPost"))));
|
||||
|
||||
assertEquals(2, results.size());
|
||||
|
||||
@ -254,8 +296,8 @@ public class GroupByMapTest extends AbstractGroupByTest {
|
||||
@Test
|
||||
public void OneToOneToMany_Projection_As_Bean_And_Constructor() {
|
||||
Map<String, User> results = USERS_W_LATEST_POST_AND_COMMENTS.transform(
|
||||
groupBy(userName).as(Projections.bean(User.class, userName,
|
||||
Projections.constructor(Post.class, postId, postName, set(qComment)).as("latestPost"))));
|
||||
groupBy(userName).as(Projections.bean(User.class, userName,
|
||||
Projections.constructor(Post.class, postId, postName, set(qComment)).as("latestPost"))));
|
||||
|
||||
assertEquals(2, results.size());
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user