Java8中是否有任何方法可以使用Streams API连接两个地图列表? 让我们说我有:
列表#1
[
{
id=1, attr1='a', attr2='b'
},
{
id=2, attr1='c', attr2='d'
},
{
id=3, attr1='e', attr2='f'
}
]
列表#2
[
{
id=1, attr3='x', attr4='y'
},
{
id=2, attr3='x', attr4='z'
},
{
id=3, attr3='z', attr4='y'
}
]
现在我想通过密钥ID加入这两个列表(只列出一个SQL连接), 输出将是:
[
{
id=1, attr1='a', attr2='b', attr3='x', attr4='y'
},
{
id=2, attr1='c', attr2='d', attr3='x', attr4='z'
},
{
id=3, attr1='e', attr2='f', attr3='z', attr4='y'
}
]
非常感谢!
答案 0 :(得分:3)
final List<HashMap<String, String>> joinedById = list1.stream()
.flatMap(m1 -> list2.stream()
.filter(y -> m1.get("id").equals(y.get("id")))
.map(m2 -> new HashMap<String, String>() {{
putAll(m1);
putAll(m2);
}}))
.collect(Collectors.toList());
答案 1 :(得分:0)
有很多种方式,无论是否有流。最好的方法取决于您没有给我们的更准确的输入要求。以下内容适用于您的问题中的示例列表:
if (list1.size() != list2.size()) {
throw new IllegalStateException("Lists don’t match, not same size");
}
List<Map<String, Character>> comnbinedList = IntStream.range(0, list1.size())
.mapToObj(i -> {
Map<String, Character> m1 = list1.get(i);
Character id1 = m1.get("id");
Map<String, Character> m2 = list2.get(i);
Character id2 = m1.get("id");
if (! id1.equals(id2)) {
throw new IllegalStateException("Lists don’t match, id " + id1 + " != " + id2);
}
HashMap<String, Character> mergedMap = new HashMap<>(m1);
mergedMap.putAll(m2);
return mergedMap;
})
.collect(Collectors.toList());
结果是:
[{id=1, attr2=b, attr1=a, attr4=y, attr3=x}, {id=2, attr2=d, attr1=c, attr4=z, attr3=x}, {id=3, attr2=f, attr1=e, attr4=y, attr3=z}]
当然,您需要声明"id"
一个常量。
答案 2 :(得分:0)
您在地图中使用ID键的数据结构;有点让这有点不寻常,但这是一个流收集器的例子。由于您的地图值均为int
和String
,因此我使用了Map<String, Object>
import java.util.*;
public class JoinTwoListofMaps {
public static void main(String... args){
List<Map<String, Object>> list1 = new ArrayList<>();
List<Map<String, Object>> list2 = new ArrayList<>();
Map<String, Object> map1_1 = new HashMap<>();
map1_1.put("id",1);
map1_1.put("attr1","a");
map1_1.put("attr2","b");
list1.add(map1_1);
Map<String, Object> map2_1 = new HashMap<>();
map2_1.put("id",1);
map2_1.put("attr3","x");
map2_1.put("attr4","y");
list2.add(map2_1);
System.out.println(joinTwoListOfMaps(list1, list2));
}
@SafeVarargs
public static List<Map<String, Object>> joinTwoListOfMaps(List<Map<String, Object>>... listsOfMaps){
List<Map<String, Object>> finalList = Arrays.stream(listsOfMaps).collect(ArrayList::new, List::addAll, List::addAll);
return finalList.stream().collect(ArrayList::new, (list, mapToMerge) ->{
Optional<Map<String, Object>> mapWithSameID = list.stream()
.filter(map -> map.get("id").equals(mapToMerge.get("id"))).findFirst();
if (mapWithSameID.isPresent()) mapWithSameID.get().putAll(mapToMerge);
else list.add(mapToMerge);
}, ArrayList::addAll);
}
}