Ali*_*aka 30 java java-8 java-stream
我有一堆通用项目。我想打印第一个项目的类名+ toString()所有项目的类名。
如果我有一个Iterable,它将看起来像这样:
Iterable<E> itemIter = ...;
boolean first = true;
for (E e : itemIter) {
if (first) {
first = false;
System.out.println(e.getClass().getSimpleName());
}
System.out.println(e);
}
Run Code Online (Sandbox Code Playgroud)
我可以Stream<T>使用流API 在流()上执行此操作吗?
*请注意,这是关于流的问题,而不是关于迭代器的问题。我有一个流-没有迭代器。
Rus*_*lan 16
有一个StreamEx库可以扩展标准Java的Stream API。使用StreamEx.of(Iterator)和peekFirst:
StreamEx.of(itemIter.iterator())
.peekFirst(e -> System.out.println(e.getClass().getSimpleName()))
.forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)
And*_*cus 10
本机解决方案: Stream Java中不可重用。这意味着,消费流只能完成一次。如果从流中获得第一个元素,则可以对其进行一次以上的迭代。
解决方法是创建与第一个流相同的另一个流或获取第一个项目,然后创建一个流,如下所示:
Stream<E> stream = StreamSupport.stream(Spliterators.spliteratorUnknownSize(sourceIterator, Spliterator.ORDERED), false);
E firstElement = itemIter.next();
stream.foreach(...);
Run Code Online (Sandbox Code Playgroud)
编辑
实际上并没有任何“复制”流的方法,您需要保留一个迭代器/集合。在这里了解更多。当流耗尽时,当涉及到内存时,由于没有用处,因此可以由垃圾收集器进行收集。Stream本身所占用的空间不会比其起源的迭代器多。请记住,流可能是无限的。当前操作的元素存储在内存中。
Hol*_*ger 10
如果您的起点是a,Stream并且想要保留其所有属性和惰性,则可以使用以下解决方案:
public static <E> Stream<E> forFirst(Stream<E> stream, Consumer<? super E> c) {
boolean parallel = stream.isParallel();
Spliterator<E> sp = stream.spliterator();
return StreamSupport.stream(() -> {
if(sp.getExactSizeIfKnown() == 0) return sp;
Stream.Builder<E> b = Stream.builder();
if(!sp.tryAdvance(b.andThen(c))) return sp;
return Stream.concat(b.build(), StreamSupport.stream(sp, parallel)).spliterator();
}, sp.characteristics(), parallel);
}
Run Code Online (Sandbox Code Playgroud)
例如,当您将其与
List<String> list = new ArrayList<>(List.of("foo", "bar", "baz"));
Stream<String> stream = forFirst(
list.stream().filter(s -> s.startsWith("b")),
s -> System.out.println(s+" ("+s.getClass().getSimpleName()+')')
).map(String::toUpperCase);
list.add(1, "blah");
System.out.println(stream.collect(Collectors.joining(" | ")));
Run Code Online (Sandbox Code Playgroud)
它将打印
blah (String)
BLAH | BAR | BAZ
Run Code Online (Sandbox Code Playgroud)
表示在开始终端操作(collect)之前该处理将不会开始,因此将先前的更新反映到了source List。
您可以滥用减少:
Stream<E> stream = ...;
System.out.println(stream
.reduce("",(out,e) ->
out + (out.isEmpty() ? e.getClass().getSimpleName()+"\n" : "")
+ e));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1676 次 |
| 最近记录: |