gpt4 book ai didi

java - 是否可以在 Java 8 中执行一个惰性 groupby,返回一个流?

转载 作者:搜寻专家 更新时间:2023-10-31 20:11:19 26 4
gpt4 key购买 nike

我有一些大型文本文件,我想通过对其行进行分组来处理。

我尝试使用新的流媒体功能,例如

return FileUtils.readLines(...) 
.parallelStream()
.map(...)
.collect(groupingBy(pair -> pair[0]));

问题是,据我所知,这会生成一个 map 。

有没有什么方法可以生成像上面那样的高级代码,例如生成一个条目流?

更新:我正在寻找的是类似 python 的 itertools.groupby 的东西.我的文件已经排序(按对[0]),我只想一个一个地加载这些组。

我已经有了迭代解决方案。我只是想知道是否有更明确的方式来做到这一点。顺便说一句,使用 Guava 或其他第 3 方库不会是一个大问题。

最佳答案

您要完成的任务与分组的任务完全不同。 groupingBy 不依赖于 Stream 元素的顺序,而是依赖于应用于分类器 Function< 的 Map 算法 的结果。

您想要的是将具有共同属性值的相邻项目折叠到一个 List 项目中。甚至没有必要让 Stream 按该属性排序,只要您可以保证所有具有相同属性值的项目都聚集在一起即可。

也许可以将这个任务表述为一个缩减,但对我来说,结果结构看起来太复杂了。

因此,除非将对此功能的直接支持添加到 Stream 中,否则基于迭代器的方法对我来说看起来最实用:

class Folding<T,G> implements Spliterator<Map.Entry<G,List<T>>> {
static <T,G> Stream<Map.Entry<G,List<T>>> foldBy(
Stream<? extends T> s, Function<? super T, ? extends G> f) {
return StreamSupport.stream(new Folding<>(s.spliterator(), f), false);
}
private final Spliterator<? extends T> source;
private final Function<? super T, ? extends G> pf;
private final Consumer<T> c=this::addItem;
private List<T> pending, result;
private G pendingGroup, resultGroup;

Folding(Spliterator<? extends T> s, Function<? super T, ? extends G> f) {
source=s;
pf=f;
}
private void addItem(T item) {
G group=pf.apply(item);
if(pending==null) pending=new ArrayList<>();
else if(!pending.isEmpty()) {
if(!Objects.equals(group, pendingGroup)) {
if(pending.size()==1)
result=Collections.singletonList(pending.remove(0));
else {
result=pending;
pending=new ArrayList<>();
}
resultGroup=pendingGroup;
}
}
pendingGroup=group;
pending.add(item);
}
public boolean tryAdvance(Consumer<? super Map.Entry<G, List<T>>> action) {
while(source.tryAdvance(c)) {
if(result!=null) {
action.accept(entry(resultGroup, result));
result=null;
return true;
}
}
if(pending!=null) {
action.accept(entry(pendingGroup, pending));
pending=null;
return true;
}
return false;
}
private Map.Entry<G,List<T>> entry(G g, List<T> l) {
return new AbstractMap.SimpleImmutableEntry<>(g, l);
}
public int characteristics() { return 0; }
public long estimateSize() { return Long.MAX_VALUE; }
public Spliterator<Map.Entry<G, List<T>>> trySplit() { return null; }
}

生成的折叠 Stream 的惰性特性可以通过将其应用于无限流得到最好的证明:

Folding.foldBy(Stream.iterate(0, i->i+1), i->i>>4)
.filter(e -> e.getKey()>5)
.findFirst().ifPresent(e -> System.out.println(e.getValue()));

关于java - 是否可以在 Java 8 中执行一个惰性 groupby,返回一个流?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25652982/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com