Jos*_*rdo 5 java lazy-loading java-8 java-stream
我有一些大型的文本文件,我想通过对其行进行分组来处理.
我尝试使用新的流媒体功能,比如
return FileUtils.readLines(...)
.parallelStream()
.map(...)
.collect(groupingBy(pair -> pair[0]));
Run Code Online (Sandbox Code Playgroud)
问题是,AFAIK,这会生成一个Map.
是否有任何方法可以像上面那样生成高级代码,例如,条目流?
更新:我正在寻找的是像python的itertools.groupby.我的文件已经排序(通过pair [0]),我只想逐个加载组.
我已经有了一个迭代解决方案.我只是想知道是否有更多的声明方式来做到这一点.顺便说一句,使用番石榴或其他第三方图书馆不会是一个大问题.
您想要实现的任务与分组所做的任务完全不同。不依赖于\xe2\x80\x99s 元素groupingBy的顺序,而是依赖于应用于分类器\xe2\x80\x99s 结果的 \xe2\x80\x99s 算法。StreamMapFunction
您想要的是将具有共同属性值的相邻项目折叠成一个List项目。Stream只要您可以保证具有相同属性值的所有项目都聚集在一起,甚至没有必要按该属性进行排序。
也许可以将这个任务表述为简化,但对我来说,结果结构看起来太复杂了。
\n\n因此,除非将对此功能的直接支持添加到 s 中Stream,否则基于迭代器的方法对我来说看起来最实用:
class Folding<T,G> implements Spliterator<Map.Entry<G,List<T>>> {\n static <T,G> Stream<Map.Entry<G,List<T>>> foldBy(\n Stream<? extends T> s, Function<? super T, ? extends G> f) {\n return StreamSupport.stream(new Folding<>(s.spliterator(), f), false);\n }\n private final Spliterator<? extends T> source;\n private final Function<? super T, ? extends G> pf;\n private final Consumer<T> c=this::addItem;\n private List<T> pending, result;\n private G pendingGroup, resultGroup;\n\n Folding(Spliterator<? extends T> s, Function<? super T, ? extends G> f) {\n source=s;\n pf=f;\n }\n private void addItem(T item) {\n G group=pf.apply(item);\n if(pending==null) pending=new ArrayList<>();\n else if(!pending.isEmpty()) {\n if(!Objects.equals(group, pendingGroup)) {\n if(pending.size()==1)\n result=Collections.singletonList(pending.remove(0));\n else {\n result=pending;\n pending=new ArrayList<>();\n }\n resultGroup=pendingGroup;\n }\n }\n pendingGroup=group;\n pending.add(item);\n }\n public boolean tryAdvance(Consumer<? super Map.Entry<G, List<T>>> action) {\n while(source.tryAdvance(c)) {\n if(result!=null) {\n action.accept(entry(resultGroup, result));\n result=null;\n return true;\n }\n }\n if(pending!=null) {\n action.accept(entry(pendingGroup, pending));\n pending=null;\n return true;\n }\n return false;\n }\n private Map.Entry<G,List<T>> entry(G g, List<T> l) {\n return new AbstractMap.SimpleImmutableEntry<>(g, l);\n }\n public int characteristics() { return 0; }\n public long estimateSize() { return Long.MAX_VALUE; }\n public Spliterator<Map.Entry<G, List<T>>> trySplit() { return null; }\n}\nRun Code Online (Sandbox Code Playgroud)\n\nStream通过将其应用于无限流可以最好地证明所得到的折叠的惰性本质:
Folding.foldBy(Stream.iterate(0, i->i+1), i->i>>4)\n .filter(e -> e.getKey()>5)\n .findFirst().ifPresent(e -> System.out.println(e.getValue()));\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
921 次 |
| 最近记录: |