Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

some TODOs in Iterator fixed #487 #543

Merged
merged 2 commits into from
Sep 2, 2015
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 5 additions & 13 deletions src/main/java/javaslang/collection/HashSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ public HashSet<T> filter(Predicate<? super T> predicate) {

@Override
public Option<T> findLast(Predicate<? super T> predicate) {
throw new UnsupportedOperationException("TODO");
return findFirst(predicate);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great!!

}

@Override
Expand All @@ -212,7 +212,7 @@ public HashSet<Object> flatten() {

@Override
public <U> U foldRight(U zero, BiFunction<? super T, ? super U, ? extends U> f) {
throw new UnsupportedOperationException("TODO");
return foldLeft(zero, (u, t) -> f.apply(t, u));
}

@Override
Expand Down Expand Up @@ -292,16 +292,8 @@ public String mkString(CharSequence delimiter,
@Override
public Tuple2<HashSet<T>, HashSet<T>> partition(Predicate<? super T> predicate) {
Objects.requireNonNull(predicate, "predicate is null");
HashSet<T> first = HashSet.empty();
HashSet<T> second = HashSet.empty();
for (T t : this) {
if (predicate.test(t)) {
first = first.add(t);
} else {
second = second.add(t);
}
}
return Tuple.of(first, second);
final Tuple2<Iterator<T>, Iterator<T>> p = iterator().partition(predicate);
return Tuple.of(HashSet.ofAll(p._1), HashSet.ofAll(p._2));
}

@Override
Expand All @@ -315,7 +307,7 @@ public HashSet<T> peek(Consumer<? super T> action) {

@Override
public T reduceRight(BiFunction<? super T, ? super T, ? extends T> op) {
throw new UnsupportedOperationException("TODO");
return reduceLeft(op);
}

@Override
Expand Down
159 changes: 152 additions & 7 deletions src/main/java/javaslang/collection/Iterator.java
Original file line number Diff line number Diff line change
Expand Up @@ -715,7 +715,104 @@ public Long next() {
}
}

// TODO: add static factory methods similar to Stream.from, Stream.gen, ...
/**
* Returns an infinitely iterator of int values starting from {@code from}.
* <p>
* The {@code Iterator} extends to {@code Integer.MIN_VALUE} when passing {@code Integer.MAX_VALUE}.
*
* @param value a start int value
* @return a new {@code Iterator} of int values starting from {@code from}
*/
static Iterator<Integer> from(int value) {
return new AbstractIterator<Integer>() {
private int next = value;

@Override
public boolean hasNext() {
return true;
}

@Override
public Integer next() {
return next++;
}
};
}

/**
* Returns an infinitely iterator of long values starting from {@code from}.
* <p>
* The {@code Iterator} extends to {@code Long.MIN_VALUE} when passing {@code Long.MAX_VALUE}.
*
* @param value a start long value
* @return a new {@code Iterator} of long values starting from {@code from}
*/
static Iterator<Long> from(long value) {
return new AbstractIterator<Long>() {
private long next = value;

@Override
public boolean hasNext() {
return true;
}

@Override
public Long next() {
return next++;
}
};
}

/**
* Generates an infinitely iterator using a value Supplier.
*
* @param supplier A Supplier of iterator values
* @param <T> value type
* @return A new {@code Iterator}
*/
@SuppressWarnings("unchecked")
static <T> Iterator<T> gen(Supplier<? extends T> supplier) {
Objects.requireNonNull(supplier, "supplier is null");
return new AbstractIterator<T>() {
@Override
public boolean hasNext() {
return true;
}

@Override
public T next() {
return supplier.get();
}
};
}

/**
* Generates an infinitely iterator using a function to calculate the next value
* based on the previous.
*
* @param seed The first value in the iterator
* @param f A function to calculate the next value based on the previous
* @param <T> value type
* @return A new {@code Iterator}
*/
static <T> Iterator<T> gen(T seed, Function<? super T, ? extends T> f) {
Objects.requireNonNull(f, "f is null");
return new AbstractIterator<T>() {
T next = seed;

@Override
public boolean hasNext() {
return true;
}

@Override
public T next() {
T result = next;
next = f.apply(next);
return result;
}
};
}

@Override
default Iterator<T> clear() {
Expand Down Expand Up @@ -1095,8 +1192,14 @@ public U next() {
@Override
default Tuple2<Iterator<T>, Iterator<T>> partition(Predicate<? super T> predicate) {
Objects.requireNonNull(predicate, "predicate is null");
// TODO
throw new UnsupportedOperationException("TODO");
if (!hasNext()) {
return Tuple.of(empty(), empty());
} else {
final Stream<T> that = Stream.ofAll(this);
final Iterator<T> first = that.iterator().filter(predicate);
final Iterator<T> second = that.iterator().filter(predicate.negate());
return Tuple.of(first, second);
}
}

@Override
Expand Down Expand Up @@ -1125,11 +1228,26 @@ public T next() {
}
}

@Override
default T reduceLeft(BiFunction<? super T, ? super T, ? extends T> op) {
Objects.requireNonNull(op, "op is null");
if (isEmpty()) {
throw new NoSuchElementException("reduceLeft on Nil");
} else {
Stream<T> stream = Stream.ofAll(this);
return stream.tail().foldLeft(stream.head(), op::apply);
}
}

@Override
default T reduceRight(BiFunction<? super T, ? super T, ? extends T> op) {
Objects.requireNonNull(op, "op is null");
// TODO
throw new UnsupportedOperationException("TODO");
if (isEmpty()) {
throw new NoSuchElementException("reduceLeft on Nil");
} else {
Stream<T> reversed = Stream.ofAll(this).reverse();
return reversed.tail().foldLeft(reversed.head(), (xs, x) -> op.apply(x, xs));
}
}

@Override
Expand Down Expand Up @@ -1334,8 +1452,35 @@ public T next() {

@Override
default Iterator<T> takeRight(int n) {
// TODO
throw new UnsupportedOperationException("TODO");
if (n <= 0) {
return empty();
} else {
final Iterator<T> that = this;
return new Iterator<T>() {
private Queue<T> queue = Queue.empty();

@Override
public boolean hasNext() {
while (that.hasNext()) {
queue = queue.append(that.next());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would call queue.enqueue(that.next()) (which is the same)

if(queue.length() > n) {
queue = queue.dequeue()._2;
}
}
return queue.length() > 0;
}

@Override
public T next() {
if (!hasNext()) {
EMPTY.next();
}
final Tuple2<T, Queue<T>> t = queue.dequeue();
queue = t._2;
return t._1;
}
};
}
}

@Override
Expand Down
3 changes: 1 addition & 2 deletions src/main/java/javaslang/collection/Seq.java
Original file line number Diff line number Diff line change
Expand Up @@ -726,8 +726,7 @@ default T reduceRight(BiFunction<? super T, ? super T, ? extends T> op) {
if (isEmpty()) {
throw new NoSuchElementException("reduceRight on Nil");
} else {
final Seq<T> reversed = reverse();
return reversed.tail().foldLeft(reversed.head(), (xs, x) -> op.apply(x, xs));
return iterator().reduceRight(op);
}
}

Expand Down
10 changes: 5 additions & 5 deletions src/main/java/javaslang/collection/Stream.java
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ static <T> Collector<T, ArrayList<T>, Stream<T>> collector() {
* @return a new Stream of int values starting from {@code from}
*/
static Stream<Integer> from(int value) {
return new Cons<>(() -> value, () -> from(value + 1));
return Stream.ofAll(Iterator.from(value));
}

/**
Expand All @@ -135,7 +135,7 @@ static Stream<Integer> from(int value) {
* @return a new Stream of long values starting from {@code from}
*/
static Stream<Long> from(long value) {
return new Cons<>(() -> value, () -> from(value + 1));
return Stream.ofAll(Iterator.from(value));
}

/**
Expand All @@ -148,7 +148,7 @@ static Stream<Long> from(long value) {
@SuppressWarnings("unchecked")
static <T> Stream<T> gen(Supplier<? extends T> supplier) {
Objects.requireNonNull(supplier, "supplier is null");
return new Cons<>((Supplier<T>) supplier, () -> gen(supplier));
return Stream.ofAll(Iterator.gen(supplier));
}

/**
Expand All @@ -162,7 +162,7 @@ static <T> Stream<T> gen(Supplier<? extends T> supplier) {
*/
static <T> Stream<T> gen(T seed, Function<? super T, ? extends T> f) {
Objects.requireNonNull(f, "f is null");
return new Stream.Cons<>(() -> seed, () -> gen(f.apply(seed), f));
return Stream.ofAll(Iterator.gen(seed, f));
}

/**
Expand Down Expand Up @@ -1150,7 +1150,7 @@ default Stream<T> takeRight(int n) {
} else if (length() <= n) {
return this;
} else {
return reverse().take(n).reverse();
return Stream.ofAll(iterator().takeRight(n));
}
}

Expand Down
25 changes: 0 additions & 25 deletions src/test/java/javaslang/collection/HashSetTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -345,16 +345,6 @@ public void shouldFoldRightNil() {
// TODO
}

@Override
public void shouldThrowWhenReduceRightNullOperator() {
throw new NullPointerException(); // TODO
}

@Override
public void shouldThrowWhenReduceRightNil() {
throw new NoSuchElementException(); // TODO
}

@Override
public void shouldFindLastOfNil() {
// TODO
Expand Down Expand Up @@ -385,16 +375,6 @@ public void shouldSerializeDeserializeNonNil() {
// TODO
}

@Override
public void shouldPartitionIntsInOddAndEvenHavingOddAndEventNumbers() {
// TODO
}

@Override
public void shouldPartitionIntsInOddAndEvenHavingOnlyEvenNumbers() {
// TODO
}

@Override
public void shouldSpanNonNil() {
// TODO
Expand All @@ -410,11 +390,6 @@ public void shouldReturnSomeTailWhenCallingTailOptionOnNonNil() {
// TODO
}

@Override
public void shouldPartitionIntsInOddAndEvenHavingOnlyOddNumbers() {
// TODO
}

@Override
public void shouldSlideNonNilBySize1() {
// TODO
Expand Down
41 changes: 41 additions & 0 deletions src/test/java/javaslang/collection/IteratorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,45 @@ boolean isThisLazyJavaslangObject() {
int getPeekNonNilPerformingAnAction() {
return 3;
}

// -- static from(int)

@Test
public void shouldGenerateIntStream() {
assertThat(Iterator.from(-1).take(3)).isEqualTo(Iterator.of(-1, 0, 1));
}

@Test
public void shouldGenerateTerminatingIntStream() {
//noinspection NumericOverflow
assertThat(Iterator.from(Integer.MAX_VALUE).take(2)).isEqualTo(Iterator.of(Integer.MAX_VALUE, Integer.MAX_VALUE + 1));
}

// -- static from(long)

@Test
public void shouldGenerateLongStream() {
assertThat(Iterator.from(-1L).take(3)).isEqualTo(Iterator.of(-1L, 0L, 1L));
}

@Test
public void shouldGenerateTerminatingLongStream() {
//noinspection NumericOverflow
assertThat(Iterator.from(Long.MAX_VALUE).take(2)).isEqualTo(Iterator.of(Long.MAX_VALUE, Long.MAX_VALUE + 1));
}

// -- static gen(Supplier)

@Test
public void shouldGenerateInfiniteStreamBasedOnSupplier() {
assertThat(Iterator.gen(() -> 1).take(13).reduce((i, j) -> i + j)).isEqualTo(13);
}

// -- static gen(T, Function)

@Test
public void shouldGenerateInfiniteStreamBasedOnSupplierWithAccessToPreviousValue() {
assertThat(Iterator.gen(2, (i) -> i + 2).take(3).reduce((i, j) -> i + j)).isEqualTo(12);
}

}