Skip to content

Commit

Permalink
Merge 56583f7 into 384c065
Browse files Browse the repository at this point in the history
  • Loading branch information
solderra committed Mar 6, 2016
2 parents 384c065 + 56583f7 commit 5f999f9
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 0 deletions.
52 changes: 52 additions & 0 deletions src/main/java/com/annimon/stream/Stream.java
Original file line number Diff line number Diff line change
Expand Up @@ -659,7 +659,59 @@ public int compare(T o1, T o2) {
public <K> Stream<Map.Entry<K, List<T>>> groupBy(final Function<? super T, ? extends K> classifier) {
return Stream.of( collect(Collectors.groupingBy(classifier)) );
}

/**
* Partitions {@code Stream} into {@code List}s according to the given classifier function. In contrast
* to {@link #groupBy(Function)}, this method assumes that the elements of the stream are sorted.
* Because of this assumption, it does not need to first collect all elements and then partition them.
* Instead, it can emit a {@code List} of elements when it reaches the first element that does not
* belong to the same chunk as the previous elements.
* <p>
* <p>This is an intermediate operation.
*
* @param <K> the type of the keys, which are the result of the classifier function
* @param classifier the classifier function
* @return the new stream
*/
public <K> Stream<List<T>> chunkBy(final Function<? super T, ? extends K> classifier) {
return new Stream<List<T>>(new LsaIterator<List<T>>() {
private T next;
private boolean peekedNext;

@Override
public boolean hasNext() {
return peekedNext || iterator.hasNext();
}

@Override
public List<T> next() {
K key = classifier.apply(peek());

List<T> list = new ArrayList<T>();
do {
list.add(takeNext());
}
while (iterator.hasNext() && key.equals(classifier.apply(peek())));

return list;
}

private T takeNext() {
T element = peek();
peekedNext = false;
return element;
}

private T peek() {
if (!peekedNext) {
next = iterator.next();
peekedNext = true;
}
return next;
}
});
}

/**
* Perform provided action to each elements.
*
Expand Down
14 changes: 14 additions & 0 deletions src/test/java/com/annimon/stream/StreamTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,20 @@ public void accept(Map.Entry<Boolean, List<Integer>> entry) {
assertEquals("[2, 3, 2, 3, 2, 3]", pc2.toString());
}

@Test
public void testChunkBy() {
final PrintConsumer<List<Integer>> consumer = new PrintConsumer<List<Integer>>();

Stream.of(1, 1, 2, 2, 2, 3, 1).chunkBy(new Function<Integer, Integer>() {
@Override
public Integer apply(Integer value) {
return value;
}
}).forEach(consumer);

assertEquals("[1, 1][2, 2, 2][3][1]", consumer.toString());
}

@Test
public void testPeek() {
final PrintConsumer<Integer> consumer = new PrintConsumer<Integer>();
Expand Down

0 comments on commit 5f999f9

Please sign in to comment.