假设我有一个 List<Banana> bananas
。 Banana类的定义如下:
Banana.java
public class Banana{
String name;
Long weight;
Long price;
// getters & setters
}
香蕉列表包含:
[
{"banana1", 10, 20},
{"banana1", 10, 20},
{"banana1", 10, 20},
{"banana2", 20, 30},
{"banana2", 30, 30},
{"banana3", 50, 40},
]
我想在这里做的是按照香蕉的名称进行分组,其中总和权重列和&amp;价格栏(单独),以便我可以得到这个结果:
[
{"banana1", 30, 60},
{"banana2", 50, 60},
{"banana3", 50, 40},
]
提前致谢。
答案 0 :(得分:6)
您可以使用合并功能将CIRCLENAME | ALARMNAME | COUNT
Delhi | Fire & Smoke | 189
Mumbai | Mains Fail | 20
UP West | Predicted_Site Down | 380
Punjab | Mains Fail | 1
Kerala | Site Down | 55
Mumbai | Shelter Temperature High | 3
Gujarat | Mains Fail | 189
Kerala | Mains Fail | 198
UP West | Site Down | 16
Punjab | Shelter Temperature High | 1
Gujarat | Shelter Temperature High | 21
Maharashtra & Goa | Site Down | 1
Kerala | Shelter Temperature High | 23
Gujarat | Fire & Smoke | 14
Kerala | Fire & Smoke | 7
Delhi | Site Down | 154
UP West | Mains Fail | 470
Haryana | Mains Fail | 19
Punjab | Predicted_Site Down | 5
Mumbai | Fire & Smoke | 1
UP West | Shelter Temperature High | 92
Mumbai | Site Down | 9
UP West | Fire & Smoke | 79
Delhi | Mains Fail | 3663
Punjab | Site Down | 12
Gujarat | Site Down | 38
Delhi | Shelter Temperature High | 266
Mumbai | Predicted_Site Down | 4
分组:
Collectors.toMap
其中Map<String,Banana> bananasByName =
bananas.stream()
.collect(Collectors.toMap(Banana::getName,
Function.identity(),
(b1,b2)->{
b1.addWeightAndPrice(b2); return b1;
}));
是addWeightAndPrice
类的实例方法,它将传递的Banana
的权重和价格添加到调用它的Banana
实例。< / p>
如果您不想改变原始Banana
实例,可以更改合并功能以创建新的Banana
实例,并为其添加两个输入的权重和价格{{ 1}}实例。
答案 1 :(得分:1)
通过Eran完成经过全面测试的the java online compiler后,{{3}}的答案:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.function.Consumer;
import java.util.Map;
import java.util.function.*;
import java.util.stream.*;
import java.util.StringJoiner;
public class Java8ForEachExample {
public static void main(String[] args) {
//creating sample Collection
List<Banana> myList = new ArrayList<>();
myList.add(new Banana("B1",5,30));
myList.add(new Banana("B1",3,60));
myList.add(new Banana("B2",1,30));
myList.add(new Banana("B2",4,20));
myList.add(new Banana("B2",7,100));
// Eran's code here:
Map<String,Banana> bananasByName =
myList.stream()
.collect(Collectors.toMap(Banana::getName,
Function.identity(),
(b1,b2)->{b1.addWeightAndPrice(b2); return b1;}));
// End of Eran's code
bananasByName.entrySet().forEach(e -> {
System.out.println(e.getKey() + " : " + e.getValue());
});
}
}
class Banana{
private String name;
public int weight;
public int price;
public Banana(String name, int weight, int price) {
this.name = name;
this.weight = weight;
this.price = price;
}
public String getName() {
return name;
}
public int getWeight() {
return weight;
}
public int getPrice() {
return price;
}
public void addWeightAndPrice(Banana other) {
this.price +=other.getPrice();
this.weight +=other.getWeight();
}
@Override
public String toString() {
return (new StringJoiner(", ")).add(name).add(Integer.toString(weight)).
add(Integer.toString(price)).toString();
}
}
输出:
B2 : B2, 12, 150
B1 : B1, 8, 90
答案 2 :(得分:0)
另一个解决方案类似于:
我通过将其分解为三步来简化解决方案。定义BiFunction
和Function
。
第一个功能
这个BiFunction
得到两个Banana对象并返回单个Banana对象,它总结了期望的属性。(价格,重量)
BiFunction<Banana, Banana, Banana> function =
(o1, o2) -> new Banana(o2.getName(), o1.getWeight() +o2.getWeight(),
o1.getPrice() + o2.getPrice());
和第二个功能
此函数获取Banana对象列表并返回单个Banana。
Function<List<Banana>, Banana> function2 =
l -> l.stream()
.reduce(new Banana("",0l,0l),(o1, o2) -> function.apply(o1, o2));
最后
List<Banana> bananaList = bananas.stream()
.collect(Collectors.groupingBy(Banana::getName)).values()
.stream()
.map(function2::apply)
.collect(Collectors.toList());
List<Banana> bananaList = bananas.stream()
.collect(Collectors.groupingBy(Banana::getName)).values()
.stream()
.map(bananas1 -> bananas1
.stream()
.reduce(new Banana("",0l,0l),
(banana1,banana2)->new Banana(banana2.getName(),
banana1.getWeight() + banana2.getWeight(),
banana1.getPrice() + banana2.getPrice())))
.collect(Collectors.toList());