java stream分组,并在一次迭代中找到前10名
它与此不同,因为我想在一次迭代中解决这个问题 假设我有以下实体:java stream分组,并在一次迭代中找到前10名,java,java-8,java-stream,Java,Java 8,Java Stream,它与此不同,因为我想在一次迭代中解决这个问题 假设我有以下实体: public static class Hospital { private AREA area; private int patients; public Hospital(AREA area, int patients) { this.area = area; this.patients = patients; } public AREA getAre
public static class Hospital {
private AREA area;
private int patients;
public Hospital(AREA area, int patients) {
this.area = area;
this.patients = patients;
}
public AREA getArea() {
return area;
}
public void setArea(AREA area) {
this.area = area;
}
public int getPatients() {
return patients;
}
public void setPatients(int patients) {
this.patients = patients;
}
}
public enum AREA {
AREA1,
AREA2,
AREA3
}
现在,我列出了一份医院名单,我想找出病人最多的地区,以下是我迄今为止所做的工作:
public static void main(String[] args) {
List<Hospital> list = Arrays.asList(
new Hospital(AREA.AREA1, 20),
new Hospital(AREA.AREA2, 10),
new Hospital(AREA.AREA1, 10),
new Hospital(AREA.AREA3, 40),
new Hospital(AREA.AREA2, 10));
Map<AREA, Integer> map = findTopTen(list);
for (AREA area : map.keySet())
System.out.println(area);
}
public static Map<AREA, Integer> findTopTen(Iterable<Hospital> iterable) {
Map<AREA, Integer> map = StreamSupport.stream(iterable.spliterator(), false)
.collect(Collectors.groupingBy(Hospital::getArea,
Collectors.summingInt(Hospital::getPatients)));
for (Map.Entry<AREA, Integer> area : map.entrySet())
System.out.println(area.getKey() + "...." + area.getValue());
return map.entrySet().stream()
.sorted((e1, e2) -> e2.getValue() - e1.getValue())
.collect(Collectors.toMap(Map.Entry::getKey,
Map.Entry::getValue, (o, o2) -> o,
LinkedHashMap::new));
}
publicstaticvoidmain(字符串[]args){
List=Arrays.asList(
新医院(1区、20区),
新医院(2区、10区),
新医院(1区、10区),
新医院(3区、40区),
新医院(2区、10区);
Map Map=findTopTen(列表);
用于(区域:map.keySet())
系统输出打印LN(面积);
}
公共静态映射findTopTen(Iterable Iterable){
Map Map=StreamSupport.stream(iterable.spliterator(),false)
.collect(收集器).groupingBy(医院::getArea,
汇总(医院::获取患者));
对于(Map.Entry区域:Map.entrySet())
System.out.println(area.getKey()+“…”+area.getValue());
返回map.entrySet().stream()
.sorted((e1,e2)->e2.getValue()-e1.getValue())
.collect(Collectors.toMap(Map.Entry::getKey、,
Map.Entry::getValue,(o,o2)->o,
LinkedHashMap::new));
}
很明显,我已经迭代了两次,以找到其中大多数患者的前十个区域(一次用于按区域对医院进行分组并计算该组的总和,另一次用于查找前十个区域)
现在我想知道的是:
1)有没有更好的方法在一个流中解决这个问题,从而在一次迭代中解决这个问题?
2)在一次迭代中执行此操作是否有任何性能优势,解决此类问题的最佳实践是什么?(在我看来,一方面,当我调用
collect
这是一个终端操作时,它第一次迭代我的iterable并将中间结果保存在另一个对象中,在我的代码中,我将该对象命名为iterationOneResult,因此使用一个流并调用collect一次将忽略中间结果,这是u另一方面,在java中使用sing stream在一次迭代中解决此问题将复杂性从O(2n)降低到O(n))使用stream在一次迭代中很难做到这一点,但使用一个流链可以更简洁
Map<AREA, Integer> map = list.stream()
.collect(Collectors.groupingBy(Hospital::getArea, Collectors.summingInt(Hospital::getPatients)))
.entrySet().stream()
.sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
.limit(10)
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
.entrySet().stream()之后的rigth
谢谢你的回答,顺便说一句,考虑到性能,我想在一次迭代中完成,我想在这里讨论这样做是否对性能有好处,在你的方法中,收集时间意味着两次独立的迭代。@Ruslan如果这纯粹是一个基于复杂性的问题,那么你可能需要创建另一个线程请注意,另一方面,在谈论绩效时,不要忘记创建基准。对于我还想建议的内容,请参考第(1)部分是在链接问题中的行上尝试解决方案。在java Stream API中,当您调用collect时,上一个迭代结束,上一个流关闭。您前面提到的答案和另一个问题链接都通过调用collect两次在两次迭代中解决了此问题。我想准确地解决此问题一次迭代。请仔细阅读我的问题,它与您提到的其他问题不同。我想在一次迭代@Naman中解决这个问题
.peek(e -> System.out.println(e.getKey() + " " + e.getValue()))