我有一个通用项目流。我想打印第一个项目的类名,即所有项目的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);
}
我可以在流上执行此操作吗(流
*请注意,这是一个关于流的问题——不是关于迭代器的问题。我有一个流——不是一个迭代器。
本机解决方案:Java中的Stream
不可重用。这意味着,消费流只能完成一次。如果您从流中获取第一个元素,您可以再次迭代它。
解决方法是创建与第一个相同的另一个流,或者获取第一个项目然后创建一个流,类似于这样:
Stream<E> stream = StreamSupport.stream(Spliterators.spliteratorUnknownSize(sourceIterator, Spliterator.ORDERED), false);
E firstElement = itemIter.next();
stream.foreach(...);
编辑
实际上没有任何方法可以“复制”一个流,您需要保留一个迭代器/集合。这里有更多关于它的信息。当涉及到内存时,一旦流耗尽,它可以被垃圾收集器收集,因为它没有任何用处。流本身并不比它起源的迭代器占用更多的空间。请记住,流可能是无限的。当前操作的元素存储在内存中。
如果您的起点是一个< code >流,并且您希望保留它的所有属性和惰性,下面的解决方案就可以了:
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);
}
当你用它与
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(" | ")));
它会打印出来
blah (String)
BLAH | BAR | BAZ
表明在开始终端操作(< code>collect)之前不会开始处理,因此反映了之前对source List
的更新。
有一个< code>StreamEx库,它扩展了标准Java的流API。使用< code > streamex . of(Iterator)和< code>peekFirst:
StreamEx.of(itemIter.iterator())
.peekFirst(e -> System.out.println(e.getClass().getSimpleName()))
.forEach(System.out::println);
我目前正在使用java。尼奥。频道选择器 问题-调用选择器的选择方法只返回一个值 问:我需要在每次读/写后调用SocketChannel上的关闭吗(我希望不是!)?如果没有,SocketChannel对任何读/写操作都不可用的原因是什么? 很抱歉,我不能发布代码,但我希望我已经清楚地解释了这个问题,有人可以提供帮助。我已经搜索了答案,我发现你不能在SocketChannel连接关闭后重新使用它,但
问题内容: 我有一个像下面这样的列表,其中第一个元素是id,另一个是字符串: 我只想从此元组列表创建ID列表,如下所示: 我将使用此列表,因此它必须是整数值的列表。 问题答案:
因此,我正在研究以下json: 我想检索联系人的类型为,并且只检索第一个返回的联系人。 将jsonpath与此路径一起使用时,“$…contacts[?(@.contactType=='S')].name”始终返回字符串数组,因为筛选操作始终将结果作为数组返回。 所以我尝试了“$联系人[?(@.contactType='S')].name[0]”和“$联系人[?(@.contactType='S'
问题内容: 我有一个数组: 我想获得此数组的第一个元素。预期结果: 字符串 一个要求: 它不能通过引用传递来完成 ,所以不是一个好的解决方案。 我怎样才能做到这一点? 问题答案: 原始答案,但代价昂贵(O(n)): 在O(1)中: 其他用例等 如果修改(就重置数组指针而言)不是问题,则可以使用: 如果需要数组“副本”,则从理论上讲应该更有效: 使用PHP 5.4+(但如果为空,则可能导致索引错误)
问题内容: 我有一个。我想获取具有特定用户名的流中(第一个)用户的索引。我并不想实际上要求对它们进行描述,而只是具有相同的用户名。 我可以想到执行此操作的丑陋方法(重复和计数),但是感觉应该有一个不错的方法可以执行此操作,可能是使用Streams。到目前为止,我拥有的最好的是: 这不是我写过的最糟糕的代码,但这不是很好。它也不是那么灵活,因为它依赖于一个映射类型的函数,该函数具有描述您要寻找的属性
问题内容: 我们创建了一个日志,该日志在运行TestNG测试时输出到控制台: 稍后,在测试期间,日志中将填充详细信息,以使我们知道正在执行的操作: 现在,它正在按照您的期望进行打印: 我想将此打印输出在同一行上: 几毫秒后: LogFactory有可能吗? 问题答案: 在不确切知道您正在使用哪个 日志记录库的 情况下,我想 除非您想在其他地方显式指定换行符,否则 答案几乎肯定 不是 。 在(和)框