Java8连接两个映射列表
Java8中是否有任何方法使用Streams API连接两个映射列表? 假设我有: 清单1Java8连接两个映射列表,java,dictionary,join,merge,java-stream,Java,Dictionary,Join,Merge,Java Stream,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=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'
}
]
非常感谢 有很多方法,有流也有无流。最好的方法取决于更精确的输入要求,而您还没有给我们。以下内容适用于您问题中的示例列表:
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声明为常量。有很多方法,有流和无流。最好的方法取决于更精确的输入要求,而您还没有给我们。以下内容适用于您问题中的示例列表:
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为常量。在map中使用id键的数据结构;这有点不寻常,但这里有一个流收集器的例子。因为你们的映射值都是int和String,所以我使用了map
在地图中使用id键的数据结构;这有点不寻常,但这里有一个流收集器的例子。因为你们的映射值都是int和String,所以我使用了map
你试了什么?这不是一个代码编写服务。它看起来很像Javascript,但可能只是伪代码然而,映射在实际的Java代码中是什么样子的?我假设id是键,但是第一个列表中的attrib1和attrib2是什么?值对象的属性?嵌套集合中的元素?可以在java 8中进行集合连接。参考请解决您的问题。@Thomas抱歉,我没有说此结构表示映射列表,id、attr1、attr2、attr3和attr4是键。这是否意味着您映射的键类型是字符串?值类型,是整数、字符、对象还是什么?此外,在您的示例中,是否需要列表来保存具有相同id值1、2和3的地图?如果其中一个列表中有一张“额外”的地图怎么办?它们的顺序是一样的吗?你试了什么?这不是一个代码编写服务。它看起来很像Javascript,但可能只是伪代码然而,映射在实际的Java代码中是什么样子的?我假设id是键,但是第一个列表中的attrib1和attrib2是什么?值对象的属性?嵌套集合中的元素?可以在java 8中进行集合连接。参考请解决您的问题。@Thomas抱歉,我没有说此结构表示映射列表,id、attr1、attr2、attr3和attr4是键。这是否意味着您映射的键类型是字符串?值类型,是整数、字符、对象还是什么?此外,在您的示例中,是否需要列表来保存具有相同id值1、2和3的地图?如果其中一个列表中有一张“额外”的地图怎么办?它们的顺序一样吗?
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);
}
}
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());