Skip to content

Commit

Permalink
Merge pull request #1684 from ashrko619/scan-methods
Browse files Browse the repository at this point in the history
Reimplemented Collections.scan methods
  • Loading branch information
danieldietrich authored Nov 23, 2016
2 parents 507654a + c8c3ef5 commit 765071b
Show file tree
Hide file tree
Showing 22 changed files with 63 additions and 96 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ public M retainAll(Iterable<? extends Tuple2<K, V>> elements) {
@Override
public M scan(Tuple2<K, V> zero, BiFunction<? super Tuple2<K, V>, ? super Tuple2<K, V>, ? extends Tuple2<K, V>> operation) {
Objects.requireNonNull(operation, "operation is null");
return (M) Collections.scanLeft(this, zero, operation, Queue.empty(), Queue::append, this::createFromEntries);
return (M) Collections.scanLeft(this, zero, operation, this::createFromEntries);
}

@Override
Expand Down
8 changes: 2 additions & 6 deletions javaslang/src/main/java/javaslang/collection/Array.java
Original file line number Diff line number Diff line change
Expand Up @@ -1052,17 +1052,13 @@ public Array<T> scan(T zero, BiFunction<? super T, ? super T, ? extends T> opera
@Override
public <U> Array<U> scanLeft(U zero, BiFunction<? super U, ? super T, ? extends U> operation) {
Objects.requireNonNull(operation, "operation is null");
return Collections.scanLeft(this, zero, operation,
new java.util.ArrayList<>(), (c, u) -> {
c.add(u);
return c;
}, Array::ofAll);
return Collections.scanLeft(this, zero, operation, Array::ofAll);
}

@Override
public <U> Array<U> scanRight(U zero, BiFunction<? super T, ? super U, ? extends U> operation) {
Objects.requireNonNull(operation, "operation is null");
return Collections.scanRight(this, zero, operation, List.empty(), List::prepend, Value::toArray);
return Collections.scanRight(this, zero, operation, Array::ofAll);
}

@Override
Expand Down
15 changes: 3 additions & 12 deletions javaslang/src/main/java/javaslang/collection/BitSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -469,18 +469,12 @@ default BitSet<T> retainAll(Iterable<? extends T> elements) {

@Override
default <U> Set<U> scanLeft(U zero, BiFunction<? super U, ? super T, ? extends U> operation) {
return Collections.scanLeft(this, zero, operation, new java.util.ArrayList<>(), (c, u) -> {
c.add(u);
return c;
}, HashSet::ofAll);
return Collections.scanLeft(this, zero, operation, HashSet::ofAll);
}

@Override
default <U> Set<U> scanRight(U zero, BiFunction<? super T, ? super U, ? extends U> operation) {
return Collections.scanRight(this, zero, operation, new java.util.ArrayList<>(), (c, u) -> {
c.add(u);
return c;
}, HashSet::ofAll);
return Collections.scanRight(this, zero, operation, HashSet::ofAll);
}

@Override
Expand Down Expand Up @@ -728,10 +722,7 @@ public Tuple2<BitSet<T>, BitSet<T>> span(Predicate<? super T> predicate) {
@Override
public BitSet<T> scan(T zero, BiFunction<? super T, ? super T, ? extends T> operation) {
Objects.requireNonNull(operation, "operation is null");
return Collections.scanLeft(this, zero, operation, new java.util.ArrayList<>(), (arr, t) -> {
arr.add(t);
return arr;
}, this::createFromAll);
return Collections.scanLeft(this, zero, operation, this::createFromAll);
}

@Override
Expand Down
8 changes: 4 additions & 4 deletions javaslang/src/main/java/javaslang/collection/CharSeq.java
Original file line number Diff line number Diff line change
Expand Up @@ -802,20 +802,20 @@ public CharSeq reverse() {
}

@Override
public IndexedSeq<Character> scan(Character zero, BiFunction<? super Character, ? super Character, ? extends Character> operation) {
return scanLeft(zero, operation);
public CharSeq scan(Character zero, BiFunction<? super Character, ? super Character, ? extends Character> operation) {
return Collections.scanLeft(this, zero, operation, Iterator::toCharSeq);
}

@Override
public <U> IndexedSeq<U> scanLeft(U zero, BiFunction<? super U, ? super Character, ? extends U> operation) {
Objects.requireNonNull(operation, "operation is null");
return Collections.scanLeft(this, zero, operation, Vector.empty(), Vector::append, Function.identity());
return Collections.scanLeft(this, zero, operation, Iterator::toVector);
}

@Override
public <U> IndexedSeq<U> scanRight(U zero, BiFunction<? super Character, ? super U, ? extends U> operation) {
Objects.requireNonNull(operation, "operation is null");
return Collections.scanRight(this, zero, operation, Vector.empty(), Vector::prepend, Function.identity());
return Collections.scanRight(this, zero, operation, Iterator::toVector);
}

@Override
Expand Down
37 changes: 15 additions & 22 deletions javaslang/src/main/java/javaslang/collection/Collections.java
Original file line number Diff line number Diff line change
Expand Up @@ -110,25 +110,18 @@ static int hash(Iterable<?> iterable) {
return hashCode;
}

static <T, U, C extends Iterable<U>, R extends Traversable<U>> R scanLeft(Iterable<? extends T> elements,
U zero, BiFunction<? super U, ? super T, ? extends U> operation,
C cumulativeResult, BiFunction<C, U, C> combiner,
Function<C, R> finisher) {
U acc = zero;
cumulativeResult = combiner.apply(cumulativeResult, acc);
for (T a : elements) {
acc = operation.apply(acc, a);
cumulativeResult = combiner.apply(cumulativeResult, acc);
}
return finisher.apply(cumulativeResult);
static <T, U, R extends Traversable<U>> R scanLeft(Traversable<? extends T> traversable,
U zero, BiFunction<? super U, ? super T, ? extends U> operation, Function<Iterator<U>, R> finisher) {

final Iterator<U> iterator = traversable.iterator().scanLeft(zero, operation);
return finisher.apply(iterator);
}

static <T, U, C extends Iterable<U>, R extends Traversable<U>> R scanRight(Iterable<? extends T> elements,
U zero, BiFunction<? super T, ? super U, ? extends U> operation,
C cumulativeResult, BiFunction<C, U, C> combiner,
Function<C, R> finisher) {
final Iterator<? extends T> reversedElements = reverseIterator(elements);
return scanLeft(reversedElements, zero, (u, t) -> operation.apply(t, u), cumulativeResult, combiner, finisher);
static <T, U, R extends Traversable<U>> R scanRight(Traversable<? extends T> traversable,
U zero, BiFunction<? super T, ? super U, ? extends U> operation, Function<Iterator<U>, R> finisher) {

final Iterator<? extends T> reversedElements = reverseIterator(traversable);
return scanLeft(reversedElements, zero, (u, t) -> operation.apply(t, u), us -> finisher.apply(reverseIterator(us)));
}

@SuppressWarnings("unchecked")
Expand All @@ -137,7 +130,7 @@ static <T, S extends Seq<T>> Iterator<S> crossProduct(S empty, S seq, int power)
return Iterator.empty();
}
return Iterator.range(0, power)
.foldLeft(Iterator.of(empty), (product, ignored) -> product.flatMap(el -> seq.map(t -> (S) el.append(t))));
.foldLeft(Iterator.of(empty), (product, ignored) -> product.flatMap(el -> seq.map(t -> (S) el.append(t))));
}

static <C extends Traversable<T>, T> C tabulate(int n, Function<? super Integer, ? extends T> f, C empty, Function<T[], C> of) {
Expand Down Expand Up @@ -213,7 +206,7 @@ static <T> boolean isTraversableAgain(Iterable<? extends T> iterable) {
}

@SuppressWarnings("unchecked")
static <T> Iterator<? extends T> reverseIterator(Iterable<? extends T> iterable) {
static <T> Iterator<T> reverseIterator(Iterable<T> iterable) {
if (iterable instanceof java.util.List) {
final java.util.List<T> list = (java.util.List<T>) iterable;
return new Iterator<T>() {
Expand All @@ -225,10 +218,10 @@ static <T> Iterator<? extends T> reverseIterator(Iterable<? extends T> iterable)
@Override
public T next() { return delegate.previous(); }
};
} else if (iterable instanceof Seq) {
return ((Seq<T>) iterable).reverseIterator();
} else {
final Seq<? extends T> result = (iterable instanceof Seq) ? (Seq<T>) iterable
: Vector.ofAll(iterable);
return result.reverseIterator();
return List.<T>empty().pushAll(iterable).iterator();
}
}
}
2 changes: 1 addition & 1 deletion javaslang/src/main/java/javaslang/collection/HashMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,7 @@ public HashMap<K, V> retainAll(Iterable<? extends Tuple2<K, V>> elements) {
public HashMap<K, V> scan(
Tuple2<K, V> zero,
BiFunction<? super Tuple2<K, V>, ? super Tuple2<K, V>, ? extends Tuple2<K, V>> operation) {
return Maps.scan(this, HashMap::empty, zero, operation);
return Maps.scan(this, zero, operation, this::createFromEntries);
}

@Override
Expand Down
7 changes: 2 additions & 5 deletions javaslang/src/main/java/javaslang/collection/HashSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -716,16 +716,13 @@ public HashSet<T> scan(T zero, BiFunction<? super T, ? super T, ? extends T> ope
@Override
public <U> HashSet<U> scanLeft(U zero, BiFunction<? super U, ? super T, ? extends U> operation) {
Objects.requireNonNull(operation, "operation is null");
return Collections.scanLeft(this, zero, operation, new java.util.ArrayList<>(), (c, u) -> {
c.add(u);
return c;
}, HashSet::ofAll);
return Collections.scanLeft(this, zero, operation, HashSet::ofAll);
}

@Override
public <U> HashSet<U> scanRight(U zero, BiFunction<? super T, ? super U, ? extends U> operation) {
Objects.requireNonNull(operation, "operation is null");
return Collections.scanRight(this, zero, operation, HashSet.empty(), HashSet::add, Function.identity());
return Collections.scanRight(this, zero, operation, HashSet::ofAll);
}

@Override
Expand Down
2 changes: 1 addition & 1 deletion javaslang/src/main/java/javaslang/collection/Iterator.java
Original file line number Diff line number Diff line change
Expand Up @@ -1772,7 +1772,7 @@ default <U> Iterator<U> scanRight(U zero, BiFunction<? super T, ? super U, ? ext
if (isEmpty()) {
return of(zero);
} else {
return Collections.scanRight(this, zero, operation, Stream.empty(), Stream::prepend, Stream::iterator);
return Collections.scanRight(this, zero, operation, Function.identity());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -760,7 +760,7 @@ public LinkedHashMap<K, V> retainAll(Iterable<? extends Tuple2<K, V>> elements)
public LinkedHashMap<K, V> scan(
Tuple2<K, V> zero,
BiFunction<? super Tuple2<K, V>, ? super Tuple2<K, V>, ? extends Tuple2<K, V>> operation) {
return Maps.scan(this, LinkedHashMap::empty, zero, operation);
return Maps.scan(this, zero, operation, this::createFromEntries);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -715,16 +715,13 @@ public LinkedHashSet<T> scan(T zero, BiFunction<? super T, ? super T, ? extends
@Override
public <U> LinkedHashSet<U> scanLeft(U zero, BiFunction<? super U, ? super T, ? extends U> operation) {
Objects.requireNonNull(operation, "operation is null");
return Collections.scanLeft(this, zero, operation, new java.util.ArrayList<>(), (c, u) -> {
c.add(u);
return c;
}, LinkedHashSet::ofAll);
return Collections.scanLeft(this, zero, operation, LinkedHashSet::ofAll);
}

@Override
public <U> LinkedHashSet<U> scanRight(U zero, BiFunction<? super T, ? super U, ? extends U> operation) {
Objects.requireNonNull(operation, "operation is null");
return Collections.scanRight(this, zero, operation, List.empty(), List::prepend, LinkedHashSet::ofAll);
return Collections.scanRight(this, zero, operation, LinkedHashSet::ofAll);
}

@Override
Expand Down
4 changes: 2 additions & 2 deletions javaslang/src/main/java/javaslang/collection/List.java
Original file line number Diff line number Diff line change
Expand Up @@ -1176,13 +1176,13 @@ default List<T> scan(T zero, BiFunction<? super T, ? super T, ? extends T> opera
@Override
default <U> List<U> scanLeft(U zero, BiFunction<? super U, ? super T, ? extends U> operation) {
Objects.requireNonNull(operation, "operation is null");
return Collections.scanLeft(this, zero, operation, empty(), List::prepend, List::reverse);
return Collections.scanLeft(this, zero, operation, Iterator::toList);
}

@Override
default <U> List<U> scanRight(U zero, BiFunction<? super T, ? super U, ? extends U> operation) {
Objects.requireNonNull(operation, "operation is null");
return Collections.scanRight(this, zero, operation, empty(), List::prepend, Function.identity());
return Collections.scanRight(this, zero, operation, Iterator::toList);
}

@Override
Expand Down
4 changes: 2 additions & 2 deletions javaslang/src/main/java/javaslang/collection/Map.java
Original file line number Diff line number Diff line change
Expand Up @@ -503,13 +503,13 @@ default <U> Seq<U> map(Function<? super Tuple2<K, V>, ? extends U> mapper) {
@Override
default <U> Seq<U> scanLeft(U zero, BiFunction<? super U, ? super Tuple2<K, V>, ? extends U> operation) {
Objects.requireNonNull(operation, "operation is null");
return iterator().scanLeft(zero, operation).toStream();
return Collections.scanLeft(this, zero, operation, Iterator::toVector);
}

@Override
default <U> Seq<U> scanRight(U zero, BiFunction<? super Tuple2<K, V>, ? super U, ? extends U> operation) {
Objects.requireNonNull(operation, "operation is null");
return Collections.scanRight(this, zero, operation, Stream.empty(), Stream::prepend, Function.identity());
return Collections.scanRight(this, zero, operation, Iterator::toVector);
}

@Override
Expand Down
9 changes: 5 additions & 4 deletions javaslang/src/main/java/javaslang/collection/Maps.java
Original file line number Diff line number Diff line change
Expand Up @@ -255,11 +255,12 @@ static <K, V, M extends Map<K, V>> M replaceAll(M map, BiFunction<? super K, ? s
return (M) map.map((k, v) -> Tuple(k, function.apply(k, v)));
}

static <K, V, M extends Map<K, V>> M scan(
M map, Supplier<M> emptySupplier, Tuple2<K, V> zero,
BiFunction<? super Tuple2<K, V>, ? super Tuple2<K, V>, ? extends Tuple2<K, V>> operation) {
@SuppressWarnings("unchecked")
static <K, V, M extends Map<K, V>> M scan(M map, Tuple2<K, V> zero,
BiFunction<? super Tuple2<K, V>, ? super Tuple2<K, V>, ? extends Tuple2<K, V>> operation,
Function<Iterator<Tuple2<K, V>>, Traversable<Tuple2<K, V>>> finisher) {
Objects.requireNonNull(operation, "operation is null");
return Collections.scanLeft(map, zero, operation, emptySupplier.get(), Maps::put, Function.identity());
return (M) Collections.scanLeft(map, zero, operation, finisher);
}

static <K, V, M extends Map<K, V>> Iterator<M> sliding(M map, OfEntries<K, V, M> ofEntries, int size) {
Expand Down
4 changes: 2 additions & 2 deletions javaslang/src/main/java/javaslang/collection/Multimap.java
Original file line number Diff line number Diff line change
Expand Up @@ -415,13 +415,13 @@ default <U> Seq<U> map(Function<? super Tuple2<K, V>, ? extends U> mapper) {
@Override
default <U> Seq<U> scanLeft(U zero, BiFunction<? super U, ? super Tuple2<K, V>, ? extends U> operation) {
Objects.requireNonNull(operation, "operation is null");
return iterator().scanLeft(zero, operation).toStream();
return Collections.scanLeft(this, zero, operation, Iterator::toVector);
}

@Override
default <U> Seq<U> scanRight(U zero, BiFunction<? super Tuple2<K, V>, ? super U, ? extends U> operation) {
Objects.requireNonNull(operation, "operation is null");
return Collections.scanRight(this, zero, operation, Stream.empty(), Stream::prepend, Function.identity());
return Collections.scanRight(this, zero, operation, Iterator::toVector);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -438,19 +438,19 @@ public PriorityQueue<T> replaceAll(T currentElement, T newElement) {

@Override
public PriorityQueue<T> scan(T zero, BiFunction<? super T, ? super T, ? extends T> operation) {
return Collections.scanLeft(this, zero, operation, empty(comparator), PriorityQueue::enqueue, Function.identity());
return Collections.scanLeft(this, zero, operation, it -> ofAll(comparator, it));
}

@Override
public <U> PriorityQueue<U> scanLeft(U zero, BiFunction<? super U, ? super T, ? extends U> operation) {
Objects.requireNonNull(operation, "operation is null");
return Collections.scanLeft(this, zero, operation, empty(naturalComparator()), PriorityQueue::enqueue, Function.identity());
return Collections.scanLeft(this, zero, operation, it -> ofAll(naturalComparator(), it));
}

@Override
public <U> PriorityQueue<U> scanRight(U zero, BiFunction<? super T, ? super U, ? extends U> operation) {
Objects.requireNonNull(operation, "operation is null");
return Collections.scanRight(this, zero, operation, empty(naturalComparator()), PriorityQueue::enqueue, Function.identity());
return Collections.scanRight(this, zero, operation, it -> ofAll(naturalComparator(), it));
}

@Override
Expand Down
8 changes: 3 additions & 5 deletions javaslang/src/main/java/javaslang/collection/Queue.java
Original file line number Diff line number Diff line change
Expand Up @@ -961,15 +961,13 @@ public Queue<T> scan(T zero, BiFunction<? super T, ? super T, ? extends T> opera
@Override
public <U> Queue<U> scanLeft(U zero, BiFunction<? super U, ? super T, ? extends U> operation) {
Objects.requireNonNull(operation, "operation is null");
// prepends to the rear-list in O(1)
return Collections.scanLeft(this, zero, operation, empty(), Queue::append, Function.identity());
return Collections.scanLeft(this, zero, operation, Iterator::toQueue);
}

@Override
public <U> Queue<U> scanRight(U zero, BiFunction<? super T, ? super U, ? extends U> operation) {
// add elements in reverse order in O(1) and creates a Queue instance in O(1)
final List<U> list = Collections.scanRight(this, zero, operation, List.empty(), List::prepend, Function.identity());
return ofAll(list);
Objects.requireNonNull(operation, "operation is null");
return Collections.scanRight(this, zero, operation, Iterator::toQueue);
}

@Override
Expand Down
4 changes: 2 additions & 2 deletions javaslang/src/main/java/javaslang/collection/Stream.java
Original file line number Diff line number Diff line change
Expand Up @@ -1242,14 +1242,14 @@ default Stream<T> scan(T zero, BiFunction<? super T, ? super T, ? extends T> ope
default <U> Stream<U> scanLeft(U zero, BiFunction<? super U, ? super T, ? extends U> operation) {
Objects.requireNonNull(operation, "operation is null");
// lazily streams the elements of an iterator
return Stream.ofAll(iterator().scanLeft(zero, operation));
return Collections.scanLeft(this, zero, operation, Iterator::toStream);
}

// not lazy!
@Override
default <U> Stream<U> scanRight(U zero, BiFunction<? super T, ? super U, ? extends U> operation) {
Objects.requireNonNull(operation, "operation is null");
return Collections.scanRight(this, zero, operation, Stream.empty(), Stream::prepend, Function.identity());
return Collections.scanRight(this, zero, operation, Iterator::toStream);
}

@Override
Expand Down
4 changes: 2 additions & 2 deletions javaslang/src/main/java/javaslang/collection/Tree.java
Original file line number Diff line number Diff line change
Expand Up @@ -532,13 +532,13 @@ default Seq<T> scan(T zero, BiFunction<? super T, ? super T, ? extends T> operat
@Override
default <U> Seq<U> scanLeft(U zero, BiFunction<? super U, ? super T, ? extends U> operation) {
Objects.requireNonNull(operation, "operation is null");
return Collections.scanLeft(this, zero, operation, List.empty(), List::prepend, List::reverse);
return Collections.scanLeft(this, zero, operation, Iterator::toStream);
}

@Override
default <U> Seq<U> scanRight(U zero, BiFunction<? super T, ? super U, ? extends U> operation) {
Objects.requireNonNull(operation, "operation is null");
return Collections.scanRight(this, zero, operation, List.empty(), List::prepend, Function.identity());
return Collections.scanRight(this, zero, operation, Iterator::toStream);
}

@Override
Expand Down
2 changes: 1 addition & 1 deletion javaslang/src/main/java/javaslang/collection/TreeMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -1080,7 +1080,7 @@ public TreeMap<K, V> retainAll(Iterable<? extends Tuple2<K, V>> elements) {
public TreeMap<K, V> scan(
Tuple2<K, V> zero,
BiFunction<? super Tuple2<K, V>, ? super Tuple2<K, V>, ? extends Tuple2<K, V>> operation) {
return Maps.scan(this, this::emptyInstance, zero, operation);
return Maps.scan(this, zero, operation, this::createFromEntries);
}

@Override
Expand Down
Loading

0 comments on commit 765071b

Please sign in to comment.