[英]How can I combine objects with two fields having the same values in a list into one reduced list?
我有一個此類的對象列表:
class Item
{
private String name;
private String parentName;
private Integer someValue;
private Double anotherValue;
public Item() {}
//...elided getters/setters...
}
我有這些值的列表:
//PSEUDO CODE (Not JavaScript, but using JSON is easier to follow)
List<Item> items = [
{
"name": "Joe",
"parentName": "Frank",
"someValue": 10,
"anotherValue": 15.0
},
{
"name": "Joe",
"parentName": "Frank",
"someValue": 40,
"anotherValue": 0.5
},
{
"name": "Joe",
"parentName": "Jack",
"someValue": 10,
"anotherValue": 10.0
},
{
"name": "Jeff",
"parentName": "Frank",
"someValue": 10,
"anotherValue": 10.0
}
];
我希望將其合並到此列表中:
List<Item> items = [
{
"name": "Joe",
"parentName": "Frank",
"someValue": 50,
"anotherValue": 15.5
},
{
"name": "Joe",
"parentName": "Jack",
"someValue": 10,
"anotherValue": 10.0
},
{
"name": "Jeff",
"parentName": "Frank",
"someValue": 10,
"anotherValue": 10.0
}
];
基本上,規則是:
我將如何在Java 8流中做到這一點?
我從將它們放入水桶開始(請參見下文),但不確定從何處去:
items
.stream()
.collect(
Collectors.groupingBy(
item -> new ArrayList<String>( Arrays.asList( item.getName(), item.getParentName() ) )
)
);
collect(groupingBy())
方法返回一個映射。
如果定義以下類:
class Tuple {
String name;
String parentName;
}
那么您可以獲取以下地圖:
Map<Tuple, List<Item>> groupedItems = items.stream().collect(
groupingBy(item -> new Tuple(item.getName(), item.getParentName())));
現在您可以像這樣操作它:
List<Item> finalItems = groupedItems.entrySet().stream().map(entry ->
new Item(entry.getKey().name,
entry.getKey().parentName,
entry.getValue().stream().mapToInt(
item -> item.someValue).sum(),
entry.getValue().stream().mapToDouble(
item -> item.anotherValue).sum()))
.collect(Collectors.toList());
這是一個使用某些Java8構造的解決方案(盡管其本質上是遍歷List的循環,將項臨時存儲在Map中)。 :
List<Item> items;
Map<String, Item> masterItems;
items.forEach(item -> {
if (masterItems.containsKey(item.getName() + item.getParent())) {
Item matchedItem = masterItems.get(item.getName() + item.getParent());
matchedItem.setSomeValue(matchedItem.getSomeValue() + item.getSomeValue());
matchedItem.setOtherValue(matchedItem.getOtherValue() + item.getOtherValue());
} else {
masterItems.put(item.getName() + item.getParent(), item);
}
});
items.clear();
items.addAll(masterItems.values());
也許可以改進它以使用更多的Java8構造...我去看看我能做什么
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.