如何根据class的属性收集对象到List,然后Map到java8或11中的HashMap?
How to collect objects to List based on properties of the class and then Map to HashMap in java 8 or 11?
我有类类似于:
class Response {
Source source;
Target target;
}
class Source {
Long sourceId;
String sourceName;
}
class Target {
Long targetId;
String targetName;
}
在Response, source(sourceId,sourceName)
中对于不同的目标对象可能是相同的。
我在 Response
中输入了这 4 个属性 sourceId, sourceName, targetId, targetName
。我可以在多行上使用相同的 sourceId
、sourceName
,但 targetId
、targetName
将始终不同。
我想将所有目标对象分组到源相同的List
。
我有 List
个 Response 对象,我正在尝试对其执行 stream()
操作,例如:
Map<Source, List<Target>> res = results
.stream()
.collect(Collectors.groupingBy(
Response::getSource)
//collect to map
所以我的最终输出 JSON 看起来像:
"Response": {
"Source": {
"sourceId": "100",
"sourceName": "source1",
}
"Target": [{//grouping target objects with same source
"targetId": "10",
"targetName": "target1",
}, {
"targetId": "20",
"targetName": "target2",
}]
}
我假设 sourceName 是字符串(由于 json)
一定要是流吗?
它可能很容易像下面这样完成:
Map<Source,List<Target>> res= new HashMap<>();
for(Response response : results){
List<Target> sourceTarget = res.computeIfAbsent(response.source, list -> new ArrayList<>());
sourceTarget.add(response.target);
}
Class Source
需要正确覆盖 hashCode
和 equals
方法才能用作 Map 中的键。
但是,应该实现另一个 POJO 以包含所需的输出:
@AllArgsConstructor
class Grouped {
@JsonProperty("Source")
Source source;
@JsonProperty("Target")
List<Target> target;
}
然后响应列表可以转换如下:
List<Response> responses; // set up the input list
List<Grouped> grouped = responses.stream()
.collect(Collectors.groupingBy(
Response::getSource,
Collectors.mapping(Response::getTarget, Collectors.toList())
)) // Map<Source, List<Target>> is built
.entrySet()
.stream() // Stream<Map.Entry<Source, List<Target>>>
.map(e -> new Grouped(e.getKey(), e.getValue()))
.collect(Collectors.toList());
我有类类似于:
class Response {
Source source;
Target target;
}
class Source {
Long sourceId;
String sourceName;
}
class Target {
Long targetId;
String targetName;
}
在Response, source(sourceId,sourceName)
中对于不同的目标对象可能是相同的。
我在 Response
中输入了这 4 个属性 sourceId, sourceName, targetId, targetName
。我可以在多行上使用相同的 sourceId
、sourceName
,但 targetId
、targetName
将始终不同。
我想将所有目标对象分组到源相同的List
。
我有 List
个 Response 对象,我正在尝试对其执行 stream()
操作,例如:
Map<Source, List<Target>> res = results
.stream()
.collect(Collectors.groupingBy(
Response::getSource)
//collect to map
所以我的最终输出 JSON 看起来像:
"Response": {
"Source": {
"sourceId": "100",
"sourceName": "source1",
}
"Target": [{//grouping target objects with same source
"targetId": "10",
"targetName": "target1",
}, {
"targetId": "20",
"targetName": "target2",
}]
}
我假设 sourceName 是字符串(由于 json)
一定要是流吗?
它可能很容易像下面这样完成:
Map<Source,List<Target>> res= new HashMap<>();
for(Response response : results){
List<Target> sourceTarget = res.computeIfAbsent(response.source, list -> new ArrayList<>());
sourceTarget.add(response.target);
}
Class Source
需要正确覆盖 hashCode
和 equals
方法才能用作 Map 中的键。
但是,应该实现另一个 POJO 以包含所需的输出:
@AllArgsConstructor
class Grouped {
@JsonProperty("Source")
Source source;
@JsonProperty("Target")
List<Target> target;
}
然后响应列表可以转换如下:
List<Response> responses; // set up the input list
List<Grouped> grouped = responses.stream()
.collect(Collectors.groupingBy(
Response::getSource,
Collectors.mapping(Response::getTarget, Collectors.toList())
)) // Map<Source, List<Target>> is built
.entrySet()
.stream() // Stream<Map.Entry<Source, List<Target>>>
.map(e -> new Grouped(e.getKey(), e.getValue()))
.collect(Collectors.toList());