从Java8流获取下一项
我想从Java 8从Java8流获取下一项,java,java-8,java-stream,Java,Java 8,Java Stream,我想从Java 8流中检索并删除下一项,而不关闭此流 Stream<Integer> integerStream = Stream.iterate( 0, x -> new Integer(x + 1) ); Integer zero = integerStream.getNext(); // 0 Integer one = integerStream.getNext(); // 1 ... Stream integerStream=Stream.iterate(0,x->
流
中检索并删除下一项,而不关闭此流
Stream<Integer> integerStream = Stream.iterate( 0, x -> new Integer(x + 1) );
Integer zero = integerStream.getNext(); // 0
Integer one = integerStream.getNext(); // 1
...
Stream integerStream=Stream.iterate(0,x->new Integer(x+1));
整数零=integerStream.getNext();//0
Integer one=integerStream.getNext();//1.
...
这可能吗?是的,有一种方法可以做到这一点,但有一些限制
Stream<Integer> infiniteStream = Stream.iterate( 0, x -> new Integer(x + 1) );
Iterator<Integer> iter = infiniteStream.iterator();
Integer zero = iter.next();
Integer one = iter.next();
这在某些情况下可能会很好,但我不确定我是否会推荐这种技术。我认为它添加了一些额外的对象,从而在生成下一个元素的路径中增加了额外的方法调用
编辑评论(与您的问题无关):
- 不要使用
。改为使用新整数(val)
,它将重用已装箱的整数(如果可用),这通常适用于-128到127范围内的值Integer.valueOf(val)
- 您可以使用
而不是IntStream
,这样可以完全避免装箱开销。它没有完整的流操作,但是它有Stream
,它接受一个对基元iterate()
值进行操作的函数int
PeelingStream
提供了一种方法T getNext()
,该方法屏蔽了someWrappedStream.iterator()
的终端流操作语义:
public class PeelingStream<T> implements Stream<T> {
private Stream<T> wrapped;
public PeelingStream(Stream<T> toBeWrapped) {
this.wrapped = toBeWrapped;
}
public T getNext() {
Iterator<T> iterator = wrapped.iterator();
T next = iterator.next();
Iterable<T> remainingIterable = () -> iterator;
wrapped = StreamSupport.stream(remainingIterable.spliterator(),
false);
return next;
}
///////////////////// from here, only plain delegate methods
public Iterator<T> iterator() {
return wrapped.iterator();
}
public Spliterator<T> spliterator() {
return wrapped.spliterator();
}
public boolean isParallel() {
return wrapped.isParallel();
}
public Stream<T> sequential() {
return wrapped.sequential();
}
public Stream<T> parallel() {
return wrapped.parallel();
}
public Stream<T> unordered() {
return wrapped.unordered();
}
public Stream<T> onClose(Runnable closeHandler) {
return wrapped.onClose(closeHandler);
}
public void close() {
wrapped.close();
}
public Stream<T> filter(Predicate<? super T> predicate) {
return wrapped.filter(predicate);
}
public <R> Stream<R> map(Function<? super T, ? extends R> mapper) {
return wrapped.map(mapper);
}
public IntStream mapToInt(ToIntFunction<? super T> mapper) {
return wrapped.mapToInt(mapper);
}
public LongStream mapToLong(ToLongFunction<? super T> mapper) {
return wrapped.mapToLong(mapper);
}
public DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper) {
return wrapped.mapToDouble(mapper);
}
public <R> Stream<R> flatMap(
Function<? super T, ? extends Stream<? extends R>> mapper) {
return wrapped.flatMap(mapper);
}
public IntStream flatMapToInt(
Function<? super T, ? extends IntStream> mapper) {
return wrapped.flatMapToInt(mapper);
}
public LongStream flatMapToLong(
Function<? super T, ? extends LongStream> mapper) {
return wrapped.flatMapToLong(mapper);
}
public DoubleStream flatMapToDouble(
Function<? super T, ? extends DoubleStream> mapper) {
return wrapped.flatMapToDouble(mapper);
}
public Stream<T> distinct() {
return wrapped.distinct();
}
public Stream<T> sorted() {
return wrapped.sorted();
}
public Stream<T> sorted(Comparator<? super T> comparator) {
return wrapped.sorted(comparator);
}
public Stream<T> peek(Consumer<? super T> action) {
return wrapped.peek(action);
}
public Stream<T> limit(long maxSize) {
return wrapped.limit(maxSize);
}
public Stream<T> skip(long n) {
return wrapped.skip(n);
}
public void forEach(Consumer<? super T> action) {
wrapped.forEach(action);
}
public void forEachOrdered(Consumer<? super T> action) {
wrapped.forEachOrdered(action);
}
public Object[] toArray() {
return wrapped.toArray();
}
public <A> A[] toArray(IntFunction<A[]> generator) {
return wrapped.toArray(generator);
}
public T reduce(T identity, BinaryOperator<T> accumulator) {
return wrapped.reduce(identity, accumulator);
}
public Optional<T> reduce(BinaryOperator<T> accumulator) {
return wrapped.reduce(accumulator);
}
public <U> U reduce(U identity,
BiFunction<U, ? super T, U> accumulator,
BinaryOperator<U> combiner) {
return wrapped.reduce(identity, accumulator, combiner);
}
public <R> R collect(Supplier<R> supplier,
BiConsumer<R, ? super T> accumulator, BiConsumer<R, R> combiner) {
return wrapped.collect(supplier, accumulator, combiner);
}
public <R, A> R collect(Collector<? super T, A, R> collector) {
return wrapped.collect(collector);
}
public Optional<T> min(Comparator<? super T> comparator) {
return wrapped.min(comparator);
}
public Optional<T> max(Comparator<? super T> comparator) {
return wrapped.max(comparator);
}
public long count() {
return wrapped.count();
}
public boolean anyMatch(Predicate<? super T> predicate) {
return wrapped.anyMatch(predicate);
}
public boolean allMatch(Predicate<? super T> predicate) {
return wrapped.allMatch(predicate);
}
public boolean noneMatch(Predicate<? super T> predicate) {
return wrapped.noneMatch(predicate);
}
public Optional<T> findFirst() {
return wrapped.findFirst();
}
public Optional<T> findAny() {
return wrapped.findAny();
}
}
公共类peeringstream实现流{
私有流包装;
公共对等流(要包装的流){
this.wrapped=toBeWrapped;
}
公共T getNext(){
迭代器迭代器=wrapped.Iterator();
T next=iterator.next();
Iterable remainingIterable=()->迭代器;
wrapped=StreamSupport.stream(remainingable.spliterator(),
假);
下一步返回;
}
/////////////////////从这里开始,只有普通的委托方法
公共迭代器迭代器(){
返回wrapped.iterator();
}
公共拆分器拆分器(){
return wrapped.spliterator();
}
公共布尔值isParallel(){
返回wrapped.isParallel();
}
公共流顺序(){
返回wrapped.sequential();
}
公共流并行{
return wrapped.parallel();
}
公共流无序(){
返回已包装。无序();
}
公共流onClose(可运行的closeHandler){
返回wrapped.onClose(closeHandler);
}
公众假期结束(){
wrapped.close();
}
publicstreamfilter(Predicate我做了以下操作。原始流确实会关闭,但会创建一个与旧流行为完全相同的新流
您需要guava的com.google.common.collect.Iterators
import static com.google.common.collect.Iterators.concat;
import static com.google.common.collect.Iterators.singletonIterator;
import static java.util.Spliterators.spliteratorUnknownSize;
import static java.util.stream.StreamSupport.stream;
private <T> Stream<T> peekFirst(Stream<T> originalStream){
//This closes the original Stream
Iterator<T> originalIterator = originalStream.iterator();
if (!originalIterator.hasNext()) {
return Stream.of();
}
T firstElement = originalIterator.next();
doSomethingWithFirstElement(firstElement);
Iterator<T> newIterator = concat(
singletonIterator(firstElement),
originalIterator);
return stream(
spliteratorUnknownSize(newIterator, 0),
originalStream.isParallel());
}
import static com.google.common.collect.Iterators.concat;
导入静态com.google.common.collect.Iterators.singletonIterator;
导入静态java.util.Spliterators.spliteratorUnknownSize;
导入静态java.util.stream.StreamSupport.stream;
私有流优先(流源流){
//这将关闭原始流
迭代器originalIterator=originalStream.Iterator();
如果(!originalIterator.hasNext()){
返回流。of();
}
T firstElement=originalIterator.next();
doSomethingWithFirstElement(firstElement);
迭代器newIterator=concat(
singletonIterator(第一个元素),
原创者);
回流(
spliteratorUnknownSize(newIterator,0),
originalStream.isParallel());
}
或者你可以只使用x->x+1
,它比较短,也使用整数。valueOf
(刚刚用8u25和javap-c-p验证过)。你是想实际使用删除的项目,还是放弃它们?对于后者,。跳过(n)
是一种方法。
public class PeelingStream<T> implements Stream<T> {
private Stream<T> wrapped;
public PeelingStream(Stream<T> toBeWrapped) {
this.wrapped = toBeWrapped;
}
public T getNext() {
Iterator<T> iterator = wrapped.iterator();
T next = iterator.next();
Iterable<T> remainingIterable = () -> iterator;
wrapped = StreamSupport.stream(remainingIterable.spliterator(),
false);
return next;
}
///////////////////// from here, only plain delegate methods
public Iterator<T> iterator() {
return wrapped.iterator();
}
public Spliterator<T> spliterator() {
return wrapped.spliterator();
}
public boolean isParallel() {
return wrapped.isParallel();
}
public Stream<T> sequential() {
return wrapped.sequential();
}
public Stream<T> parallel() {
return wrapped.parallel();
}
public Stream<T> unordered() {
return wrapped.unordered();
}
public Stream<T> onClose(Runnable closeHandler) {
return wrapped.onClose(closeHandler);
}
public void close() {
wrapped.close();
}
public Stream<T> filter(Predicate<? super T> predicate) {
return wrapped.filter(predicate);
}
public <R> Stream<R> map(Function<? super T, ? extends R> mapper) {
return wrapped.map(mapper);
}
public IntStream mapToInt(ToIntFunction<? super T> mapper) {
return wrapped.mapToInt(mapper);
}
public LongStream mapToLong(ToLongFunction<? super T> mapper) {
return wrapped.mapToLong(mapper);
}
public DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper) {
return wrapped.mapToDouble(mapper);
}
public <R> Stream<R> flatMap(
Function<? super T, ? extends Stream<? extends R>> mapper) {
return wrapped.flatMap(mapper);
}
public IntStream flatMapToInt(
Function<? super T, ? extends IntStream> mapper) {
return wrapped.flatMapToInt(mapper);
}
public LongStream flatMapToLong(
Function<? super T, ? extends LongStream> mapper) {
return wrapped.flatMapToLong(mapper);
}
public DoubleStream flatMapToDouble(
Function<? super T, ? extends DoubleStream> mapper) {
return wrapped.flatMapToDouble(mapper);
}
public Stream<T> distinct() {
return wrapped.distinct();
}
public Stream<T> sorted() {
return wrapped.sorted();
}
public Stream<T> sorted(Comparator<? super T> comparator) {
return wrapped.sorted(comparator);
}
public Stream<T> peek(Consumer<? super T> action) {
return wrapped.peek(action);
}
public Stream<T> limit(long maxSize) {
return wrapped.limit(maxSize);
}
public Stream<T> skip(long n) {
return wrapped.skip(n);
}
public void forEach(Consumer<? super T> action) {
wrapped.forEach(action);
}
public void forEachOrdered(Consumer<? super T> action) {
wrapped.forEachOrdered(action);
}
public Object[] toArray() {
return wrapped.toArray();
}
public <A> A[] toArray(IntFunction<A[]> generator) {
return wrapped.toArray(generator);
}
public T reduce(T identity, BinaryOperator<T> accumulator) {
return wrapped.reduce(identity, accumulator);
}
public Optional<T> reduce(BinaryOperator<T> accumulator) {
return wrapped.reduce(accumulator);
}
public <U> U reduce(U identity,
BiFunction<U, ? super T, U> accumulator,
BinaryOperator<U> combiner) {
return wrapped.reduce(identity, accumulator, combiner);
}
public <R> R collect(Supplier<R> supplier,
BiConsumer<R, ? super T> accumulator, BiConsumer<R, R> combiner) {
return wrapped.collect(supplier, accumulator, combiner);
}
public <R, A> R collect(Collector<? super T, A, R> collector) {
return wrapped.collect(collector);
}
public Optional<T> min(Comparator<? super T> comparator) {
return wrapped.min(comparator);
}
public Optional<T> max(Comparator<? super T> comparator) {
return wrapped.max(comparator);
}
public long count() {
return wrapped.count();
}
public boolean anyMatch(Predicate<? super T> predicate) {
return wrapped.anyMatch(predicate);
}
public boolean allMatch(Predicate<? super T> predicate) {
return wrapped.allMatch(predicate);
}
public boolean noneMatch(Predicate<? super T> predicate) {
return wrapped.noneMatch(predicate);
}
public Optional<T> findFirst() {
return wrapped.findFirst();
}
public Optional<T> findAny() {
return wrapped.findAny();
}
}
@Test
public void testPeelingOffItemsFromStream() {
Stream<Integer> infiniteStream = Stream.iterate(0, x -> x + 1);
PeelingStream<Integer> peelingInfiniteStream = new PeelingStream<>(infiniteStream);
Integer one = peelingInfiniteStream.getNext();
assertThat(one, equalTo(0));
Integer two = peelingInfiniteStream.getNext();
assertThat(two, equalTo(1));
Stream<Integer> limitedStream = peelingInfiniteStream.limit(3); // 2 3 4
int sumOf234 = limitedStream.mapToInt(x -> x.intValue()).sum();
assertThat(sumOf234, equalTo(2 + 3 + 4));
}
import static com.google.common.collect.Iterators.concat;
import static com.google.common.collect.Iterators.singletonIterator;
import static java.util.Spliterators.spliteratorUnknownSize;
import static java.util.stream.StreamSupport.stream;
private <T> Stream<T> peekFirst(Stream<T> originalStream){
//This closes the original Stream
Iterator<T> originalIterator = originalStream.iterator();
if (!originalIterator.hasNext()) {
return Stream.of();
}
T firstElement = originalIterator.next();
doSomethingWithFirstElement(firstElement);
Iterator<T> newIterator = concat(
singletonIterator(firstElement),
originalIterator);
return stream(
spliteratorUnknownSize(newIterator, 0),
originalStream.isParallel());
}