如何通过两个对象属性对对象内的列表进行分组?
我正在使用 Drools 7.9.0 和 Java 8。我有一个 Result
用作返回每个匹配的 Drools 规则的类。
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
@Data
@NoArgsConstructor
public class Result implements Serializable {
private Integer id;
private String name;
private List<Occurrences> occurrences = new ArrayList<>();
public void addOccurrence(Occurrences occurrence) {
this.occurrences.add(occurrence);
}
}
执行 Drools 后,我得到一个 List<Result>
.转换为 JSON 后看起来像这样。
当前结果:
[
{
name: "Whatever"
id: 0001,
occurrences: [{
(...)
}]
},
{
name: "Whatever"
id: 0001,
occurrences: [{
(...)
}]
},
{
name: "Whatever"
id: 0002,
occurrences: [{
(...)
}]
},
{
name: "Other thing"
id: 0002,
occurrences: [{
(...)
}]
}
]
我需要对 Result
列表进行分组所以 ocurrences
按 id
分组和 name
,像这样。
预期结果:
[
{
name: "Whatever"
id: 0001,
occurrences: [{
(...)
}, {
(...)
}]
},
{
name: "Whatever"
id: 0002,
occurrences: [{
(...)
}]
},
{
name: "Other thing"
id: 0002,
occurrences: [{
(...)
}]
}
]
实现这个的最佳方法是什么?我有两个选择:
- 更改 Drools 规则以便我的
List<Result>
已经按照我需要的方式构建了。也许用addResult
创建一个类检查id
列表的方法和name
并将事件添加到正确的条目中。但这并不理想,因为它会增加规则内部的复杂性。 - 后处理我的
List<Result>
所以它将occurrences
分组通过id
和name
.但我不知道如何以优化和简单的方式做到这一点。
执行第二个选项的最佳方法是什么?
最佳答案
你可以这样做,
Map<String, List<Result>> resultsWithSameIdAndName = results.stream()
.collect(Collectors.groupingBy(r -> r.getId() + ":" + r.getName()));
List<Result> mergedResults = resultsWithSameIdAndName.entrySet().stream()
.map(e -> new Result(Integer.valueOf(e.getKey().split(":")[0]),
e.getKey().split(":")[1],
e.getValue().stream().flatMap(r -> r.getOccurrences().stream())
.collect(Collectors.toList())))
.collect(Collectors.toList());
关于java - 按多个属性对对象内的列表进行分组 : Java 8,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54444651/