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

zip*/unzip methods added #487 #508

Merged
merged 2 commits into from
Aug 24, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
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: 9 additions & 9 deletions src/main/java/javaslang/collection/HashSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ public HashSet<T> drop(int n) {
if (n <= 0) {
return this;
} else {
return HashSet.ofAll(() -> iterator().drop(n));
return HashSet.ofAll(iterator().drop(n));
}
}

Expand All @@ -181,15 +181,15 @@ public HashSet<T> dropRight(int n) {
@Override
public HashSet<T> dropWhile(Predicate<? super T> predicate) {
Objects.requireNonNull(predicate, "predicate is null");
final List<T> dropped = list.get().dropWhile(predicate);
return dropped.length() == list.get().length() ? this : HashSet.ofAll(dropped);
final HashSet<T> dropped = HashSet.ofAll(iterator().dropWhile(predicate));
Copy link
Contributor

Choose a reason for hiding this comment

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

Yay! Getting rid of list :-)

Copy link
Member Author

Choose a reason for hiding this comment

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

😄

return dropped.length() == length() ? this : dropped;
}

@Override
public HashSet<T> filter(Predicate<? super T> predicate) {
Objects.requireNonNull(predicate, "predicate is null");
final List<T> filtered = list.get().filter(predicate);
return filtered.length() == list.get().length() ? this : HashSet.ofAll(filtered);
final HashSet<T> filtered = HashSet.ofAll(iterator().filter(predicate));
return filtered.length() == length() ? this : filtered;
}

@Override
Expand Down Expand Up @@ -453,25 +453,25 @@ public HashSet<T> takeWhile(Predicate<? super T> predicate) {
@Override
public <T1, T2> Tuple2<HashSet<T1>, HashSet<T2>> unzip(Function<? super T, Tuple2<? extends T1, ? extends T2>> unzipper) {
Objects.requireNonNull(unzipper, "unzipper is null");
Tuple2<List<T1>, List<T2>> t = list.get().unzip(unzipper);
Tuple2<Iterator<T1>, Iterator<T2>> t = iterator().unzip(unzipper);
return Tuple.of(HashSet.ofAll(t._1), HashSet.ofAll(t._2));
}

@Override
public <U> HashSet<Tuple2<T, U>> zip(Iterable<U> that) {
Objects.requireNonNull(that, "that is null");
return HashSet.ofAll(list.get().zip(that));
return HashSet.ofAll(iterator().zip(that));
}

@Override
public <U> HashSet<Tuple2<T, U>> zipAll(Iterable<U> that, T thisElem, U thatElem) {
Objects.requireNonNull(that, "that is null");
return HashSet.ofAll(list.get().zipAll(that, thisElem, thatElem));
return HashSet.ofAll(iterator().zipAll(that, thisElem, thatElem));
}

@Override
public HashSet<Tuple2<T, Integer>> zipWithIndex() {
return HashSet.ofAll(list.get().zipWithIndex());
return HashSet.ofAll(iterator().zipWithIndex());
}

@Override
Expand Down
119 changes: 117 additions & 2 deletions src/main/java/javaslang/collection/Iterator.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/
package javaslang.collection;

import javaslang.Tuple;
import javaslang.Tuple2;
import javaslang.Value;
import javaslang.control.None;
Expand Down Expand Up @@ -323,7 +324,37 @@ default Iterator<T> dropRight(int n) {

@Override
default Iterator<T> dropWhile(Predicate<? super T> predicate) {
return null;
Objects.requireNonNull(predicate, "predicate is null");
if (!hasNext()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

let's do Objects.requireNonNull(predicate, "predicate is null"). I've also forgotten in in various places and will add them later...

return empty();
} else {
final Iterator<T> that = this;
return new Iterator<T>() {

private T next = null;

@Override
public boolean hasNext() {
while (next == null && that.hasNext()) {
final T value = that.next();
if(!predicate.test(value)) {
next = value;
}
}
return next != null;
}

@Override
public T next() {
if (!hasNext()) {
EMPTY.next();
}
final T result = next;
next = null;
return result;
}
};
}
}

default boolean equals(Iterator<? extends T> that) {
Expand Down Expand Up @@ -378,11 +409,13 @@ public T next() {

@Override
default Iterator<T> findAll(Predicate<? super T> predicate) {
return null;
Objects.requireNonNull(predicate, "predicate is null");
return filter(predicate);
}

@Override
default Option<T> findLast(Predicate<? super T> predicate) {
Objects.requireNonNull(predicate, "predicate is null");
return null;
}

Expand Down Expand Up @@ -569,6 +602,7 @@ public U next() {

@Override
default Tuple2<Iterator<T>, Iterator<T>> partition(Predicate<? super T> predicate) {
Objects.requireNonNull(predicate, "predicate is null");
return null;
}

Expand Down Expand Up @@ -635,6 +669,7 @@ default Iterator<Iterator<T>> sliding(int size, int step) {

@Override
default Tuple2<Iterator<T>, Iterator<T>> span(Predicate<? super T> predicate) {
Objects.requireNonNull(predicate, "predicate is null");
return null;
}

Expand Down Expand Up @@ -691,9 +726,89 @@ default Iterator<T> takeRight(int n) {

@Override
default Iterator<T> takeWhile(Predicate<? super T> predicate) {
Objects.requireNonNull(predicate, "predicate is null");
return null;
}

default <U> Iterator<Tuple2<T, U>> zip(Iterable<U> that) {
Copy link
Contributor

Choose a reason for hiding this comment

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

dito

Objects.requireNonNull(that, "that is null");
if(isEmpty()) {
return empty();
} else {
final Iterator<T> it1 = this;
final java.util.Iterator<U> it2 = that.iterator();
return new Iterator<Tuple2<T, U>>() {
@Override
public boolean hasNext() {
return it1.hasNext() && it2.hasNext();
}

@Override
public Tuple2<T, U> next() {
if (!hasNext()) {
EMPTY.next();
}
return Tuple.of(it1.next(), it2.next());
}
};
}
}

default <U> Iterator<Tuple2<T, U>> zipAll(Iterable<U> that, T thisElem, U thatElem) {
Copy link
Contributor

Choose a reason for hiding this comment

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

dito

Objects.requireNonNull(that, "that is null");
if(isEmpty()) {
return empty();
} else {
final Iterator<T> it1 = this;
final java.util.Iterator<U> it2 = that.iterator();
return new Iterator<Tuple2<T, U>>() {
@Override
public boolean hasNext() {
return it1.hasNext() || it2.hasNext();
}

@Override
public Tuple2<T, U> next() {
if (!hasNext()) {
EMPTY.next();
}
T v1 = it1.hasNext() ? it1.next() : thisElem;
U v2 = it2.hasNext() ? it2.next() : thatElem;
return Tuple.of(v1, v2);
}
};
}
}

default Iterator<Tuple2<T, Integer>> zipWithIndex() {
if(isEmpty()) {
return empty();
} else {
final Iterator<T> it1 = this;
return new Iterator<Tuple2<T, Integer>>() {
private int index = 0;
@Override
public boolean hasNext() {
return it1.hasNext();
}

@Override
public Tuple2<T, Integer> next() {
if (!hasNext()) {
EMPTY.next();
}
return Tuple.of(it1.next(), index++);
}
};
}
}

default <T1, T2> Tuple2<Iterator<T1>, Iterator<T2>> unzip(Function<? super T, Tuple2<? extends T1, ? extends T2>> unzipper) {
Objects.requireNonNull(unzipper, "unzipper is null");
final Stream<Tuple2<? extends T1, ? extends T2>> source = Stream.ofAll(this.map(unzipper::apply));
return Tuple.of(source.map(t -> (T1) t._1).iterator(), source.map(t -> (T2) t._2).iterator());
}

class ConcatIterator<T> implements Iterator<T> {

private final Iterator<? extends Iterator<? extends T>> iterators;
Expand Down
118 changes: 118 additions & 0 deletions src/test/java/javaslang/collection/HashSetTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
*/
package javaslang.collection;

import javaslang.Tuple;
import javaslang.Tuple2;
import org.assertj.core.api.*;
import org.junit.Test;

Expand Down Expand Up @@ -147,6 +149,122 @@ int getPeekNonNilPerformingAnAction() {
return 1;
}

// TODO move to traversable
// -- zip

@Test
public void shouldZipNils() {
final HashSet<Tuple2<Object, Object>> actual = empty().zip(empty());
assertThat(actual).isEqualTo(empty());
}

@Test
public void shouldZipEmptyAndNonNil() {
final HashSet<Tuple2<Object, Integer>> actual = empty().zip(of(1));
assertThat(actual).isEqualTo(empty());
}

@Test
public void shouldZipNonEmptyAndNil() {
final HashSet<Tuple2<Integer, Integer>> actual = of(1).zip(empty());
assertThat(actual).isEqualTo(empty());
}

@Test
public void shouldZipNonNilsIfThisIsSmaller() {
final HashSet<Tuple2<Integer, String>> actual = of(1, 2).zip(of("a", "b", "c"));
@SuppressWarnings("unchecked")
final HashSet<Tuple2<Integer, String>> expected = of(Tuple.of(1, "a"), Tuple.of(2, "b"));
assertThat(actual).isEqualTo(expected);
}

@Test
public void shouldZipNonNilsIfThatIsSmaller() {
final HashSet<Tuple2<Integer, String>> actual = of(1, 2, 3).zip(of("a", "b"));
@SuppressWarnings("unchecked")
final HashSet<Tuple2<Integer, String>> expected = of(Tuple.of(1, "a"), Tuple.of(2, "b"));
assertThat(actual).isEqualTo(expected);
}

@Test
public void shouldZipNonNilsOfSameSize() {
final HashSet<Tuple2<Integer, String>> actual = of(1, 2, 3).zip(of("a", "b", "c"));
@SuppressWarnings("unchecked")
final HashSet<Tuple2<Integer, String>> expected = of(Tuple.of(1, "a"), Tuple.of(2, "b"), Tuple.of(3, "c"));
assertThat(actual).isEqualTo(expected);
}

@Test(expected = NullPointerException.class)
public void shouldThrowIfZipWithThatIsNull() {
empty().zip(null);
}

// TODO move to traversable
// -- zipAll

@Test
public void shouldZipAllNils() {
// ignore
}

@Test
public void shouldZipAllEmptyAndNonNil() {
// ignore
}

@Test
public void shouldZipAllNonEmptyAndNil() {
final HashSet<?> actual = of(1).zipAll(empty(), null, null);
@SuppressWarnings("unchecked")
final HashSet<Tuple2<Integer, Object>> expected = of(Tuple.of(1, null));
assertThat(actual).isEqualTo(expected);
}

@Test
public void shouldZipAllNonNilsIfThisIsSmaller() {
final HashSet<Tuple2<Integer, String>> actual = of(1, 2).zipAll(of("a", "b", "c"), 9, "z");
@SuppressWarnings("unchecked")
final HashSet<Tuple2<Integer, String>> expected = of(Tuple.of(1, "a"), Tuple.of(2, "b"), Tuple.of(9, "c"));
assertThat(actual).isEqualTo(expected);
}

@Test
public void shouldZipAllNonNilsIfThatIsSmaller() {
final HashSet<Tuple2<Integer, String>> actual = of(1, 2, 3).zipAll(of("a", "b"), 9, "z");
@SuppressWarnings("unchecked")
final HashSet<Tuple2<Integer, String>> expected = of(Tuple.of(1, "a"), Tuple.of(2, "b"), Tuple.of(3, "z"));
assertThat(actual).isEqualTo(expected);
}

@Test
public void shouldZipAllNonNilsOfSameSize() {
final HashSet<Tuple2<Integer, String>> actual = of(1, 2, 3).zipAll(of("a", "b", "c"), 9, "z");
@SuppressWarnings("unchecked")
final HashSet<Tuple2<Integer, String>> expected = of(Tuple.of(1, "a"), Tuple.of(2, "b"), Tuple.of(3, "c"));
assertThat(actual).isEqualTo(expected);
}

@Test(expected = NullPointerException.class)
public void shouldThrowIfZipAllWithThatIsNull() {
empty().zipAll(null, null, null);
}

// TODO move to traversable
// -- zipWithIndex

@Test
public void shouldZipNilWithIndex() {
assertThat(this.<String> empty().zipWithIndex()).isEqualTo(this.<Tuple2<String, Integer>> empty());
}

@Test
public void shouldZipNonNilWithIndex() {
final HashSet<Tuple2<String, Integer>> actual = of("a", "b", "c").zipWithIndex();
@SuppressWarnings("unchecked")
final HashSet<Tuple2<String, Integer>> expected = of(Tuple.of("a", 0), Tuple.of("b", 1), Tuple.of("c", 2));
assertThat(actual).isEqualTo(expected);
}

// HashSet special cases

@Override
Expand Down