Skip to content

Commit

Permalink
Add findLast operator
Browse files Browse the repository at this point in the history
  • Loading branch information
aNNiMON committed Jun 23, 2017
1 parent 1911cdc commit 60b2240
Show file tree
Hide file tree
Showing 8 changed files with 179 additions and 2 deletions.
18 changes: 18 additions & 0 deletions stream/src/main/java/com/annimon/stream/DoubleStream.java
Expand Up @@ -951,6 +951,24 @@ public OptionalDouble findFirst() {
return OptionalDouble.empty();
}

/**
* Returns the last element wrapped by {@code OptionalDouble} class.
* If stream is empty, returns {@code OptionalDouble.empty()}.
*
* <p>This is a short-circuiting terminal operation.
*
* @return an {@code OptionalDouble} with the last element
* or {@code OptionalDouble.empty()} if the stream is empty
*/
public OptionalDouble findLast() {
return reduce(new DoubleBinaryOperator() {
@Override
public double applyAsDouble(double left, double right) {
return right;
}
});
}

/**
* Returns the single element of stream.
* If stream is empty, throws {@code NoSuchElementException}.
Expand Down
20 changes: 19 additions & 1 deletion stream/src/main/java/com/annimon/stream/IntStream.java
Expand Up @@ -1005,13 +1005,31 @@ public boolean noneMatch(IntPredicate predicate) {
* or an empty {@code OptionalInt} if the stream is empty
*/
public OptionalInt findFirst() {
if(iterator.hasNext()) {
if (iterator.hasNext()) {
return OptionalInt.of(iterator.nextInt());
} else {
return OptionalInt.empty();
}
}

/**
* Returns the last element wrapped by {@code OptionalInt} class.
* If stream is empty, returns {@code OptionalInt.empty()}.
*
* <p>This is a short-circuiting terminal operation.
*
* @return an {@code OptionalInt} with the last element
* or {@code OptionalInt.empty()} if the stream is empty
*/
public OptionalInt findLast() {
return reduce(new IntBinaryOperator() {
@Override
public int applyAsInt(int left, int right) {
return right;
}
});
}

/**
* Returns the single element of stream.
* If stream is empty, throws {@code NoSuchElementException}.
Expand Down
18 changes: 18 additions & 0 deletions stream/src/main/java/com/annimon/stream/LongStream.java
Expand Up @@ -967,6 +967,24 @@ public OptionalLong findFirst() {
return OptionalLong.empty();
}

/**
* Returns the last element wrapped by {@code OptionalLong} class.
* If stream is empty, returns {@code OptionalLong.empty()}.
*
* <p>This is a short-circuiting terminal operation.
*
* @return an {@code OptionalLong} with the last element
* or {@code OptionalLong.empty()} if the stream is empty
*/
public OptionalLong findLast() {
return reduce(new LongBinaryOperator() {
@Override
public long applyAsLong(long left, long right) {
return right;
}
});
}

/**
* Returns the single element of stream.
* If stream is empty, throws {@code NoSuchElementException}.
Expand Down
20 changes: 19 additions & 1 deletion stream/src/main/java/com/annimon/stream/Stream.java
Expand Up @@ -1768,7 +1768,7 @@ public Optional<IntPair<T>> findIndexed(int from, int step,
*
* <p>This is a short-circuiting terminal operation.
*
* @return an {@code Optional} with first element
* @return an {@code Optional} with the first element
* or {@code Optional.empty()} if stream is empty
*/
public Optional<T> findFirst() {
Expand All @@ -1778,6 +1778,24 @@ public Optional<T> findFirst() {
return Optional.empty();
}

/**
* Returns the last element wrapped by {@code Optional} class.
* If stream is empty, returns {@code Optional.empty()}.
*
* <p>This is a short-circuiting terminal operation.
*
* @return an {@code Optional} with the last element
* or {@code Optional.empty()} if the stream is empty
*/
public Optional<T> findLast() {
return reduce(new BinaryOperator<T>() {
@Override
public T apply(T left, T right) {
return right;
}
});
}

/**
* Returns the single element of stream.
* If stream is empty, throws {@code NoSuchElementException}.
Expand Down
@@ -0,0 +1,22 @@
package com.annimon.stream.doublestreamtests;

import com.annimon.stream.DoubleStream;
import org.junit.Test;
import static com.annimon.stream.test.hamcrest.OptionalDoubleMatcher.hasValue;
import static com.annimon.stream.test.hamcrest.OptionalDoubleMatcher.isEmpty;
import static org.junit.Assert.assertThat;

public final class FindLastTest {

@Test
public void testFindLast() {
assertThat(DoubleStream.of(0.012, 10.347, 3.039, 19.84, 100d).findLast(),
hasValue(100d));

assertThat(DoubleStream.of(100d).findLast(),
hasValue(100d));

assertThat(DoubleStream.empty().findLast(),
isEmpty());
}
}
@@ -0,0 +1,22 @@
package com.annimon.stream.intstreamtests;

import com.annimon.stream.IntStream;
import org.junit.Test;
import static com.annimon.stream.test.hamcrest.OptionalIntMatcher.hasValue;
import static com.annimon.stream.test.hamcrest.OptionalIntMatcher.isEmpty;
import static org.junit.Assert.assertThat;

public final class FindLastTest {

@Test
public void testFindLast() {
assertThat(IntStream.of(3, 10, 19, 4, 50).findLast(),
hasValue(50));

assertThat(IntStream.of(50).findLast(),
hasValue(50));

assertThat(IntStream.empty().findFirst(),
isEmpty());
}
}
@@ -0,0 +1,22 @@
package com.annimon.stream.longstreamtests;

import com.annimon.stream.LongStream;
import org.junit.Test;
import static com.annimon.stream.test.hamcrest.OptionalLongMatcher.hasValue;
import static com.annimon.stream.test.hamcrest.OptionalLongMatcher.isEmpty;
import static org.junit.Assert.assertThat;

public final class FindLastTest {

@Test
public void testFindLast() {
assertThat(LongStream.of(3, 10, 19, 4, 50).findLast(),
hasValue(50L));

assertThat(LongStream.of(50).findLast(),
hasValue(50L));

assertThat(LongStream.empty().findLast(),
isEmpty());
}
}
@@ -0,0 +1,39 @@
package com.annimon.stream.streamtests;

import com.annimon.stream.Functions;
import com.annimon.stream.Optional;
import com.annimon.stream.Stream;
import com.annimon.stream.test.hamcrest.OptionalMatcher;
import org.junit.Test;
import static com.annimon.stream.test.hamcrest.OptionalMatcher.isPresent;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;

public final class FindLastTest {

@Test
public void testFindLast() {
Optional<Integer> result = Stream.rangeClosed(0, 10)
.findLast();
assertThat(result, isPresent());
assertNotNull(result.get());
assertEquals(10, (int) result.get());
}

@Test
public void testFindLastOnEmptyStream() {
assertThat(Stream.empty().findLast(), OptionalMatcher.isEmpty());
}

@Test
public void testFindLastAfterFiltering() {
Optional<Integer> result = Stream.range(1, 100)
.filter(Functions.remainder(6))
.findLast();

assertThat(result, isPresent());
assertNotNull(result.get());
assertEquals(96, (int) result.get());
}
}

0 comments on commit 60b2240

Please sign in to comment.