Java 8 Stream如何将2个大小不等的列表与自定义逻辑合并以拾取重复项
我有两个地图对象列表Java 8 Stream如何将2个大小不等的列表与自定义逻辑合并以拾取重复项,java,java-8,java-stream,Java,Java 8,Java Stream,我有两个地图对象列表 "list1": [ { "partyId": "1", "accountId": "1", "sourceSystem": "1", }, { "partyId": "2", "accountId": "2", "sourceSystem": "2", }] 这是列表2 "list2": [ { "partyId": "3", "a
"list1": [
{
"partyId": "1",
"accountId": "1",
"sourceSystem": "1",
},
{
"partyId": "2",
"accountId": "2",
"sourceSystem": "2",
}]
这是列表2
"list2": [
{
"partyId": "3",
"accountId": "3",
"sourceSystem": "3",
},
{
"partyId": "1",
"accountId": "2",
"sourceSystem": "2",
}]
现在我需要合并list1和list2来获得这个输出
"merged": [
{
"partyId": "1",
"accountId": "1",
"sourceSystem": "1",
},
{
"partyId": "2",
"accountId": "2",
"sourceSystem": "2",
},
{
"partyId": "3",
"accountId": "3",
"sourceSystem": "3",
}]
您可以看到它合并了列表1和列表2中的1、2和3。另外,由于列表2中有一个partyId=1(也在列表1中),但详细信息(accountId和sourceSystem)不同,因此选择了列表1中的partyId=1
如何使用Java8流实现这一点?或者,唯一的方法是将它们转换为java对象并执行for循环。一种方法可以是迭代第一个列表,并使用
partyId
作为键和Party
作为值作为映射进行收集:
Map<String, CustomObject> customObjectMap = customObjectList1.stream()
.collect(Collectors.toMap(CustomObject::getPartyId, customObject -> customObject, (a, b) -> b));
从映射中检索值作为最终输出
List<CustomObject> merged = new ArrayList<>(customObjectMap.values());
然后根据现有关键帧从另一个列表中删除对象
customObjectList2.removeIf(p -> partyIds.contains(p.getPartyId()));
最后将所有对象添加到一个对象列表中
customObjectList1.addAll(customObjectList2); // customObjectList1 is now your 'merged'
你可以一次就这么做
List<Map<String, String>> resultMap = Stream.concat(mapListOne.stream(), mapListTwo.stream())
.collect(Collectors.groupingBy(m -> m.get("partyId"), Collectors.toList()))
.entrySet().stream()
.map(e -> e.getValue().get(0))
.collect(Collectors.toList());
List resultMap=Stream.concat(mapListOne.Stream(),mapListTwo.Stream())
.collect(Collectors.groupingBy(m->m.get(“partyId”),Collectors.toList())
.entrySet().stream()
.map(e->e.getValue().get(0))
.collect(Collectors.toList());
这是一个两步计算,首先计算每个partyId值的映射的列表
,然后获取每个列表
上的第一个元素,以计算最终结果。如果逻辑只是第一个列表中的所有项加上第二个列表中与第一个列表中的项不匹配的所有项,然后:
List<Map<String,String>> result = Stream.concat(list1.stream(),
list2.stream().filter(m2 -> list1.stream()
.noneMatch(m1 -> m1.get("partyId").equals(m2.get("partyId"))))
.collect(Collectors.toList());
List result=Stream.concat(list1.Stream(),
list2.stream().filter(m2->list1.stream())
.noneMatch(m1->m1.get(“partyId”).equals(m2.get(“partyId”))
.collect(Collectors.toList());
。我注意到,或者说唯一的方法就是将它们转换为java对象……是的,请。使用Map
获取类似类型的具体信息没有什么意义。我只剩下一个问题。你怎么知道这个“e->e.getValue().get(0)”将从列表1返回元素?保证在哪里?Stream.concat
和List
都尊重顺序。因此,如果您先给listOne,它将接受它。
List<Map<String, String>> resultMap = Stream.concat(mapListOne.stream(), mapListTwo.stream())
.collect(Collectors.groupingBy(m -> m.get("partyId"), Collectors.toList()))
.entrySet().stream()
.map(e -> e.getValue().get(0))
.collect(Collectors.toList());
List<Map<String,String>> result = Stream.concat(list1.stream(),
list2.stream().filter(m2 -> list1.stream()
.noneMatch(m1 -> m1.get("partyId").equals(m2.get("partyId"))))
.collect(Collectors.toList());