Skip to content

Commit bebcff8

Browse files
committed
- fix #19
1 parent ef79ada commit bebcff8

File tree

6 files changed

+180
-42
lines changed

6 files changed

+180
-42
lines changed

src/main/java/br/com/zbra/androidlinq/AbstractStream.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,22 +41,22 @@ public <K> Stream<Grouping<K, T>> groupBy(Selector<T, K> keySelector) {
4141
}
4242

4343
@Override
44-
public <R> Stream<T> orderBy(Selector<T, R> keySelector, Comparator<R> comparator) {
45-
return new OrderByStream<>(this, keySelector, comparator);
44+
public <R> OrderedStream<T> orderBy(Selector<T, R> keySelector, Comparator<R> comparator) {
45+
return OrderByStream.createAscending(this, keySelector, comparator);
4646
}
4747

4848
@Override
49-
public <R extends Comparable<R>> Stream<T> orderBy(Selector<T, R> keySelector) {
49+
public <R extends Comparable<R>> OrderedStream<T> orderBy(Selector<T, R> keySelector) {
5050
return orderBy(keySelector, R::compareTo);
5151
}
5252

5353
@Override
54-
public <R> Stream<T> orderByDescending(Selector<T, R> keySelector, Comparator<R> comparator) {
55-
return new OrderByDescendingStream<>(this, keySelector, comparator);
54+
public <R> OrderedStream<T> orderByDescending(Selector<T, R> keySelector, Comparator<R> comparator) {
55+
return OrderByStream.createDescending(this, keySelector, comparator);
5656
}
5757

5858
@Override
59-
public <R extends Comparable<R>> Stream<T> orderByDescending(Selector<T, R> keySelector) {
59+
public <R extends Comparable<R>> OrderedStream<T> orderByDescending(Selector<T, R> keySelector) {
6060
return orderByDescending(keySelector, R::compareTo);
6161
}
6262

src/main/java/br/com/zbra/androidlinq/OrderByDescendingStream.java

Lines changed: 0 additions & 23 deletions
This file was deleted.

src/main/java/br/com/zbra/androidlinq/OrderByStream.java

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,31 @@
33
import br.com.zbra.androidlinq.delegate.Comparator;
44
import br.com.zbra.androidlinq.delegate.Selector;
55

6+
import java.util.ArrayList;
67
import java.util.Collections;
78
import java.util.Iterator;
89
import java.util.List;
910

10-
class OrderByStream<T, TComparable> extends AbstractStream<T> {
11+
class OrderByStream<T> extends AbstractStream<T> implements OrderedStream<T> {
1112

1213
private final Stream<T> stream;
13-
private final java.util.Comparator<T> comparator;
14+
private final QueuedComparators<T> queuedComparators;
1415

15-
OrderByStream(Stream<T> stream, Selector<T, TComparable> selector, Comparator<TComparable> comparator) {
16+
static <T, TComparable> OrderedStream<T> createAscending(Stream<T> stream, Selector<T, TComparable> selector, Comparator<TComparable> comparator) {
17+
OrderByStream<T> orderByStream = new OrderByStream<>(stream);
18+
orderByStream.thenBy(selector, comparator);
19+
return orderByStream;
20+
}
21+
22+
static <T, TComparable> OrderedStream<T> createDescending(Stream<T> stream, Selector<T, TComparable> selector, Comparator<TComparable> comparator) {
23+
OrderByStream<T> orderByStream = new OrderByStream<>(stream);
24+
orderByStream.thenByDescending(selector, comparator);
25+
return orderByStream;
26+
}
27+
28+
private OrderByStream(Stream<T> stream) {
1629
this.stream = stream;
17-
this.comparator = (T t1, T t2) -> comparator.compare(selector.select(t1), selector.select(t2));
30+
this.queuedComparators = new QueuedComparators<>();
1831
}
1932

2033
@Override
@@ -24,17 +37,59 @@ public int count() {
2437

2538
@Override
2639
public Iterator<T> iterator() {
27-
return getIterator(comparator);
40+
return getIterator(queuedComparators);
2841
}
2942

3043
@Override
3144
protected Iterator<T> reverseIterator() {
32-
return getIterator(Collections.reverseOrder(comparator));
45+
return getIterator(Collections.reverseOrder(queuedComparators));
3346
}
3447

3548
private Iterator<T> getIterator(java.util.Comparator<T> comparator) {
3649
List<T> list = stream.toList();
3750
Collections.sort(list, comparator);
3851
return list.iterator();
3952
}
53+
54+
@Override
55+
public <TKey> OrderedStream<T> thenBy(Selector<T, TKey> keySelector, Comparator<TKey> comparator) {
56+
this.queuedComparators.addComparator((T t1, T t2) -> comparator.compare(keySelector.select(t1), keySelector.select(t2)));
57+
return this;
58+
}
59+
60+
@Override
61+
public <TKey extends Comparable<TKey>> OrderedStream<T> thenBy(Selector<T, TKey> keySelector) {
62+
thenBy(keySelector, TKey::compareTo);
63+
return this;
64+
}
65+
66+
@Override
67+
public <TKey> OrderedStream<T> thenByDescending(Selector<T, TKey> keySelector, Comparator<TKey> comparator) {
68+
this.queuedComparators.addComparator((T t1, T t2) -> comparator.compare(keySelector.select(t1), keySelector.select(t2)) * -1);
69+
return this;
70+
}
71+
72+
@Override
73+
public <TKey extends Comparable<TKey>> OrderedStream<T> thenByDescending(Selector<T, TKey> keySelector) {
74+
thenByDescending(keySelector, TKey::compareTo);
75+
return this;
76+
}
77+
78+
private static class QueuedComparators<T> implements java.util.Comparator<T> {
79+
private List<java.util.Comparator<T>> comparators = new ArrayList<>();
80+
81+
@Override
82+
public int compare(T o1, T o2) {
83+
int size = comparators.size();
84+
int compare = 0;
85+
for (int i = 0; i < size && compare == 0; i++) {
86+
compare = comparators.get(i).compare(o1, o2);
87+
}
88+
return compare;
89+
}
90+
91+
public void addComparator(java.util.Comparator<T> comparator) {
92+
comparators.add(comparator);
93+
}
94+
}
4095
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package br.com.zbra.androidlinq;
2+
3+
import br.com.zbra.androidlinq.delegate.Comparator;
4+
import br.com.zbra.androidlinq.delegate.Selector;
5+
6+
public interface OrderedStream<T> extends Stream<T> {
7+
8+
/**
9+
* Performs a subsequent ordering of the elements in a sequence in ascending order by using a specified comparator.
10+
*
11+
* @param keySelector A function to extract a key from an element.
12+
* @param comparator An Comparator to compare keys.
13+
* @param <TKey> The type of the key returned by keySelector.
14+
* @return An Stream of type T whose elements are sorted according to a key.
15+
*/
16+
public <TKey> OrderedStream<T> thenBy(Selector<T, TKey> keySelector, Comparator<TKey> comparator);
17+
18+
/**
19+
* Performs a subsequent ordering of the elements in a sequence in ascending order according to a key.
20+
*
21+
* @param keySelector A function to extract a key from an element.
22+
* @param <TKey> The type of the key returned by keySelector.
23+
* @return An Stream of type T whose elements are sorted according to a key.
24+
*/
25+
public <TKey extends Comparable<TKey>> OrderedStream<T> thenBy(Selector<T, TKey> keySelector);
26+
27+
/**
28+
* Performs a subsequent ordering of the elements in a sequence in descending order by using a specified comparer.
29+
*
30+
* @param keySelector A function to extract a key from an element.
31+
* @param comparator An Comparator to compare keys.
32+
* @param <TKey> The type of the key returned by keySelector.
33+
* @return An Stream of type T whose elements are sorted according to a key.
34+
*/
35+
public <TKey> OrderedStream<T> thenByDescending(Selector<T, TKey> keySelector, Comparator<TKey> comparator);
36+
37+
/**
38+
* Performs a subsequent ordering of the elements in a sequence in descending order, according to a key.
39+
*
40+
* @param keySelector A function to extract a key from an element.
41+
* @param <TKey> The type of the key returned by keySelector.
42+
* @return An Stream of type T whose elements are sorted according to a key.
43+
*/
44+
public <TKey extends Comparable<TKey>> OrderedStream<T> thenByDescending(Selector<T, TKey> keySelector);
45+
46+
}

src/main/java/br/com/zbra/androidlinq/Stream.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public interface Stream<T> extends Iterable<T> {
6868
* @param <TKey> The type of the key returned by keySelector.
6969
* @return An Stream of type T whose elements are sorted according to a key.
7070
*/
71-
public <TKey> Stream<T> orderBy(Selector<T, TKey> keySelector, Comparator<TKey> comparator);
71+
public <TKey> OrderedStream<T> orderBy(Selector<T, TKey> keySelector, Comparator<TKey> comparator);
7272

7373
/**
7474
* Sorts the elements of a sequence in ascending order according to a key.
@@ -77,7 +77,7 @@ public interface Stream<T> extends Iterable<T> {
7777
* @param <TKey> The type of the key returned by keySelector.
7878
* @return An Stream of type T whose elements are sorted according to a key.
7979
*/
80-
public <TKey extends Comparable<TKey>> Stream<T> orderBy(Selector<T, TKey> keySelector);
80+
public <TKey extends Comparable<TKey>> OrderedStream<T> orderBy(Selector<T, TKey> keySelector);
8181

8282
/**
8383
* Sorts the elements of a sequence in descending order according to a key.
@@ -87,7 +87,7 @@ public interface Stream<T> extends Iterable<T> {
8787
* @param <TKey> The type of the key returned by keySelector.
8888
* @return An Stream of type T whose elements are sorted according to a key.
8989
*/
90-
public <TKey> Stream<T> orderByDescending(Selector<T, TKey> keySelector, Comparator<TKey> comparator);
90+
public <TKey> OrderedStream<T> orderByDescending(Selector<T, TKey> keySelector, Comparator<TKey> comparator);
9191

9292
/**
9393
* Sorts the elements of a sequence in descending order according to a key.
@@ -96,7 +96,7 @@ public interface Stream<T> extends Iterable<T> {
9696
* @param <TKey> The type of the key returned by keySelector.
9797
* @return An Stream of type T whose elements are sorted according to a key.
9898
*/
99-
public <TKey extends Comparable<TKey>> Stream<T> orderByDescending(Selector<T, TKey> keySelector);
99+
public <TKey extends Comparable<TKey>> OrderedStream<T> orderByDescending(Selector<T, TKey> keySelector);
100100

101101
/**
102102
* Reverses the order of the sequence.

src/test/groovy/br/com/zbra/androidlinq/StreamTest.groovy

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ class StreamTest extends GroovyTestCase {
9898
void testOrderBy() {
9999
def integers = 0..9
100100
def integersDescending = 9..0
101+
def numbersComparator = { n1, n2 -> n1 - n2 }
101102
def shuffledItems = []
102103

103104
shuffledItems.addAll(integers)
@@ -112,14 +113,14 @@ class StreamTest extends GroovyTestCase {
112113
// orderBy ascending with comparator
113114
assert integers ==
114115
stream(shuffledItems)
115-
.orderBy({ n -> n }, { n1, n2 -> n1 - n2 })
116+
.orderBy({ n -> n }, numbersComparator)
116117
.toList()
117118

118119

119120
// orderBy count()
120121
assert shuffledItems.size() ==
121122
stream(shuffledItems)
122-
.orderBy({ n -> n }, { n1, n2 -> n1 - n2 })
123+
.orderBy({ n -> n }, numbersComparator)
123124
.count()
124125

125126
// orderBy descending
@@ -131,7 +132,7 @@ class StreamTest extends GroovyTestCase {
131132
// orderBy descending with comparator
132133
assert integersDescending ==
133134
stream(shuffledItems)
134-
.orderByDescending({ n -> n }, { n1, n2 -> n1 - n2 })
135+
.orderByDescending({ n -> n }, numbersComparator)
135136
.toList()
136137

137138
// reverse cohesion
@@ -140,6 +141,65 @@ class StreamTest extends GroovyTestCase {
140141

141142
assert stream(shuffledItems).orderByDescending({ n -> n }).toList() ==
142143
stream(shuffledItems).orderBy({ n -> n }).reverse().toList()
144+
145+
146+
// thenBy & thenByDescending over orderBy
147+
def matrix = [[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], [3, 1], [3, 2], [3, 3]]
148+
def shuffledMatrix = []
149+
150+
shuffledMatrix.addAll(matrix)
151+
Collections.shuffle(shuffledMatrix)
152+
153+
assert [[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], [3, 1], [3, 2], [3, 3]] ==
154+
stream(shuffledMatrix)
155+
.orderBy({n -> n['0']})
156+
.thenBy({n -> n['1']})
157+
.toList()
158+
159+
assert [[1, 3], [1, 2], [1, 1], [2, 3], [2, 2], [2, 1], [3, 3], [3, 2], [3, 1]] ==
160+
stream(shuffledMatrix)
161+
.orderBy({n -> n['0']})
162+
.thenByDescending({ n -> n['1']})
163+
.toList()
164+
165+
166+
assert [[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], [3, 1], [3, 2], [3, 3]] ==
167+
stream(shuffledMatrix)
168+
.orderBy({n -> n['0']})
169+
.thenBy({n -> n['1']}, numbersComparator)
170+
.toList()
171+
172+
assert [[1, 3], [1, 2], [1, 1], [2, 3], [2, 2], [2, 1], [3, 3], [3, 2], [3, 1]] ==
173+
stream(shuffledMatrix)
174+
.orderBy({n -> n['0']})
175+
.thenByDescending({ n -> n['1']}, numbersComparator)
176+
.toList()
177+
178+
// thenBy & thenByDescending over orderByDescending
179+
assert [[3, 1], [3, 2], [3, 3], [2, 1], [2, 2], [2, 3], [1, 1], [1, 2], [1, 3]] ==
180+
stream(shuffledMatrix)
181+
.orderByDescending({n -> n['0']})
182+
.thenBy({n -> n['1']})
183+
.toList()
184+
185+
assert [[3, 3], [3, 2], [3, 1], [2, 3], [2, 2], [2, 1], [1, 3], [1, 2], [1, 1]] ==
186+
stream(shuffledMatrix)
187+
.orderByDescending({n -> n['0']})
188+
.thenByDescending({ n -> n['1']})
189+
.toList()
190+
191+
192+
assert [[3, 1], [3, 2], [3, 3], [2, 1], [2, 2], [2, 3], [1, 1], [1, 2], [1, 3]] ==
193+
stream(shuffledMatrix)
194+
.orderByDescending({n -> n['0']})
195+
.thenBy({n -> n['1']}, numbersComparator)
196+
.toList()
197+
198+
assert [[3, 3], [3, 2], [3, 1], [2, 3], [2, 2], [2, 1], [1, 3], [1, 2], [1, 1]] ==
199+
stream(shuffledMatrix)
200+
.orderByDescending({n -> n['0']})
201+
.thenByDescending({ n -> n['1']}, numbersComparator)
202+
.toList()
143203
}
144204

145205
void testAggregate() {

0 commit comments

Comments
 (0)