If I have a Stream<T>
, I can easily use skip(long)
to skip the first few elements of a stream. However, there seems to be no equivalent for skipping a given number of elements at the end of the stream.
The most obvious solution is to use limit(originalLength - elementsToRemoveAtEnd)
, but that requires knowing the initial length beforehand, which isn't always the case.
Is there a way to remove the last few elements of a stream of unknown length without having to collect it into a Collection
, count the elements and stream it again?
Using Stream skip() Method: The skip() method returns a stream after removing first N elements. Therefore this method can be used to skip the elements except the last one. Approach: Get the stream of elements in which the last element is to be returned.
The skip() MethodThe skip(n) method is an intermediate operation that discards the first n elements of a stream. The n parameter can't be negative, and if it's higher than the size of the stream, skip() returns an empty stream. When this stream is executed, the forEach starts asking for items.
Stream skip(n) method is used to skip the first 'n' elements from the given Stream. The skip() method returns a new Stream consisting of the remaining elements of the original Stream, after the specified n elements have been discarded in the encounter order.
The limit method of the Stream class introduced in Java 8 allows the developer to limit the number of elements that will be extracted from a stream. The limit method is useful in those applications where the user wishes to process only the initial elements that occur in the stream.
There is no general storage-free solution for Stream
s that may have an unknown length. However, you don’t need to collect the entire stream, you only need a storage as large as the number of elements you want to skip:
static <T> Stream<T> skipLastElements(Stream<T> s, int count) {
if(count<=0) {
if(count==0) return s;
throw new IllegalArgumentException(count+" < 0");
}
ArrayDeque<T> pending=new ArrayDeque<T>(count+1);
Spliterator<T> src=s.spliterator();
return StreamSupport.stream(new Spliterator<T>() {
public boolean tryAdvance(Consumer<? super T> action) {
while(pending.size()<=count && src.tryAdvance(pending::add));
if(pending.size()>count) {
action.accept(pending.remove());
return true;
}
return false;
}
public Spliterator<T> trySplit() {
return null;
}
public long estimateSize() {
return src.estimateSize()-count;
}
public int characteristics() {
return src.characteristics();
}
}, false);
}
public static void main(String[] args) {
skipLastElements(Stream.of("foo", "bar", "baz", "hello", "world"), 2)
.forEach(System.out::println);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With