[英]Java: join two lists of Map<String, Object> using Stream
I have two lists of Map<String, Object>
as shown below: 我有两个Map<String, Object>
,如下所示:
List1=[ {ID=1, actor="A", film="AA"},
{ID=1, actor="B", film="AA"} ]
List2={ [ID = 1, director="C"] }
Result = { [ID=1, actor="A", film="AA", director="C"],
[ID=1, actor="B", film="AA", director="C"] }
I want to use the Stream
class in Java 8 to join these lists. 我想使用Java 8中的Stream
类来加入这些列表。
How do I join the to get the value of Result shown? 如何加入以获得显示的结果值?
Is the Stream
class in Java 8 fast and stable if List1
and List2
are very big? 如果List1
和List2
非常大,Java 8中的Stream
类是否快速且稳定?
Ah now I understand what you want :) I don't know if there is a better way with streams but here is a solution which would work. 嗯,现在我明白了您想要的是什么:)我不知道流中是否有更好的方法,但是这里有一个可行的解决方案。
List<Map<String, String>> resultList = l1.stream()
.map(m1 -> {
Map<String, String> map = new HashMap<>();
map.putAll(m1);
l2.stream()
.filter(m2 -> map.get("ID").equals(m2.get("ID")))
.findFirst()
.ifPresent(m2 -> map.put("director", m2.get("director")));
return map;
})
.collect(Collectors.toList());
The above code generates a new List resultList
and does not modify the other lists List1
and List2
. 上面的代码生成一个新的List resultList
,而不修改其他列表List1
和List2
。 If it does not matter if List1
gets modified or not you could do it in a cleaner, more readable way. 如果List1
被修改没关系,您可以以一种更简洁,更易读的方式进行操作。
l1.forEach(m1 -> l2.stream()
.filter(m2 -> m1.get("ID").equals(m2.get("ID")))
.findFirst()
.ifPresent(m2 -> m1.putIfAbsent("director", m2.get("director"))));
This way the entries of list1
get modified. 这样, list1
的条目将被修改。 So with the above example list1
is becomes the joined list
. 因此,在上面的示例中, list1
成为joined list
。 But it's actually good practice to have methods without any side effects. 但是,拥有没有任何副作用的方法实际上是一个好习惯。 So I would not prefer the above example. 所以我不希望上面的例子。
I would recommend a method getJoinedList
which returns a new List and does not modify the other lists. 我建议使用方法getJoinedList
,该方法返回一个新列表,并且不修改其他列表。 And in this case I would not use streams
but the old-fashioned for-loop. 在这种情况下,我不会使用streams
而是使用老式的for循环。
private static List<Map<String, String>> getJoinedList(
List<Map<String, String>> l1, List<Map<String, String>> l2) {
List<Map<String, String>> result = new ArrayList<>();
for (Map<String, String> m1 : l1) {
Map<String, String> newMap = new HashMap<>();
newMap.putAll(m1);
for (Map<String, String> m2 : l2) {
if (m1.get("ID").equals(m2.get("ID"))) {
newMap.put("director", m2.get("director"));
break;
}
}
result.add(newMap);
}
return result;
}
Then you just can call the method like this. 然后,您可以调用这样的方法。
List<Map<String, String>> joinedList = getJoinedList(l1, l2);
If performance matters, you should first build an index of directors: 如果绩效很重要,则应首先建立一个董事索引:
Map<Object, Object> directors = list2.stream()
.collect(Collectors.toMap(m -> m.get("ID"), m -> m.get("director")));
Then you can merge the directors to the list entries easily: 然后,您可以轻松地将导演合并到列表条目中:
list1.stream().forEach(m -> m.put("director", directors.get(m.get("ID"))));
Accesing the director via a Map
will be faster than searching the director for each list entry. 通过Map
访问导演比在导演中搜索每个列表条目更快。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.