有没有一种简洁的方法来迭代流,同时有权访问流中的索引?
String[] names = {"Sam","Pamela", "Dave", "Pascal", "Erik"};
List<String> nameList;
Stream<Integer> indices = intRange(1, names.length).boxed();
nameList = zip(indices, stream(names), SimpleEntry::new)
.filter(e -> e.getValue().length() <= e.getKey())
.map(Entry::getValue)
.collect(toList());
Run Code Online (Sandbox Code Playgroud)
与那里给出的LINQ示例相比,这似乎相当令人失望
string[] names = { "Sam", "Pamela", "Dave", "Pascal", "Erik" };
var nameList = names.Where((c, index) => c.Length <= index + 1).ToList();
Run Code Online (Sandbox Code Playgroud)
有更简洁的方法吗?
此外,看起来拉链已移动或被移除......
我实际上试图回答这个问题如何跳过从Files.lines获得的Stream <String>的行.所以我虽然这个收集器并不能很好地并行工作:
private static Collector<String, ?, List<String>> oddLines() {
int[] counter = {1};
return Collector.of(ArrayList::new,
(l, line) -> {
if (counter[0] % 2 == 1) l.add(line);
counter[0]++;
},
(l1, l2) -> {
l1.addAll(l2);
return l1;
});
}
Run Code Online (Sandbox Code Playgroud)
但它的确有效.
编辑:它实际上没有工作; 我被我的输入集太小而无法触发任何并行性这一事实所迷惑; 见评论中的讨论.
我认为这是行不通的,因为我想到了以下两个执行计划.
counter数组在所有线程之间共享.线程t1读取Stream的第一个元素,因此满足if条件.它将第一个元素添加到其列表中.然后在他有时间更新数组值之前停止执行.
线程t2,从流的第4个元素开始,将其添加到列表中.所以我们最终得到了一个非想要的元素.
当然,既然这个收藏家似乎有效,我猜它不会那样.而且无论如何更新都不是原子的.
在这种情况下,更新没有更多的问题,但没有什么能阻止线程t2不会从流的第4个元素开始.所以他也不像那样工作.
有人能解释我基本上它是如何工作的以及为什么我的收藏家在并行运行时工作?
非常感谢你!
Java 8中的Streams是否等同于getLineNumber()?
我想在文本文件中搜索一个单词并将行号返回为Integer.这是我的搜索方法:
result = Files.lines(Paths.get(fileName))
.filter(w -> w.contains(word))
.collect(Collectors.<String> toList());
Run Code Online (Sandbox Code Playgroud) 关于如何跳过从Files.lines获得的偶数行的问题,我遵循接受的答案filterEven()方法,基于Spliterator<T>接口实现我自己的方法,例如:
public static <T> Stream<T> filterEven(Stream<T> src) {
Spliterator<T> iter = src.spliterator();
AbstractSpliterator<T> res = new AbstractSpliterator<T>(Long.MAX_VALUE, Spliterator.ORDERED)
{
@Override
public boolean tryAdvance(Consumer<? super T> action) {
iter.tryAdvance(item -> {}); // discard
return iter.tryAdvance(action); // use
}
};
return StreamSupport.stream(res, false);
}
Run Code Online (Sandbox Code Playgroud)
我可以通过以下方式使用:
Stream<DomainObject> res = Files.lines(src)
filterEven(res)
.map(line -> toDomainObject(line))
Run Code Online (Sandbox Code Playgroud)
然而,测量这种方法对下一个使用filter()副作用的方法的性能时,我注意到下一个方法表现更好:
final int[] counter = {0};
final Predicate<String> isEvenLine = item -> ++counter[0] % 2 == 0;
Stream<DomainObject> res …Run Code Online (Sandbox Code Playgroud)