从 List 创建 Map 没有给出预期的结果
creating Map from List is not giving expected result
我有两个列表对象,如下所示,我正在从中创建地图对象。
List<Class1> list1;
List<Class2> list2;
HashMap<String,String> map = new HashMap<>();
for(Class1 one : list1){
if(one.isStatus()){
map.put(one.getID(),one.getName());
}
}
//iterating second list
for(Class2 two : list2){
if(two.isPerformed()){
map.put(two.getID(),two.getName());
}
}
上面的代码工作正常,希望上面的代码使用流来编写。
下面是使用 streams() 的示例代码。
map = list1.stream().filter(one.isStatus()).collect(toMap(lst1 -> lst1.getID(), lst1.getName());
map = list2.stream().filter(...);
但是“地图”在使用 stream() 编写时没有给出预期的结果API。
我不确定您没有看到什么预期结果,但我创建了一个最小的工作示例,您应该能够根据自己的用例进行调整。
public class Main {
public static void main(String[] args) {
List<Person> personList = new ArrayList<>();
Map<Integer, String> personMap = personList.stream()
.filter(Person::isStatus)
.collect(Collectors.toMap(person -> person.id, person -> person.name));
}
private static class Person {
public String name;
public int id;
public boolean isStatus() {
return true;
}
}
}
试试这个,
List<Class1> list1;
List<Class2> list2;
Map<String, String> map1 = list1.stream().filter(Class1::isStatus).collect(Collectors.toMap(Class1::getId, Class1::getName));
Map<String, String> map2 = list2.stream().filter(Class2::isPerformed).collect(Collectors.toMap(Class2::getId, Class2::getName));
map1.putAll(map2);
这里可以应用流连接Stream.concat
以避免map.putAll
Map<String, String> map = Stream.concat(
list1.stream()
.filter(Class1::isStatus)
.map(obj -> Arrays.asList(obj.getID(), obj.getName())),
list2.stream()
.filter(Class2::isPerformed)
.map(obj -> Arrays.asList(obj.getID(), obj.getName()))
) // Stream<List<String>>
.collect(Collectors.toMap(
arr -> arr.get(0), // key - ID
arr -> arr.get(1),
(v1, v2) -> v1 // keep the first value in case of possible conflicts
));
上面的代码使用了一个合并函数(v1, v2) -> v1
来处理当同一个ID在list1
and/orlist2
中多次出现时可能发生的冲突,以保持第一个出现。
但是,以下合并函数允许将所有出现的事件合并为一个字符串值 (v1, v2) -> String.join(", ", v1, v2)
。
我有两个列表对象,如下所示,我正在从中创建地图对象。
List<Class1> list1;
List<Class2> list2;
HashMap<String,String> map = new HashMap<>();
for(Class1 one : list1){
if(one.isStatus()){
map.put(one.getID(),one.getName());
}
}
//iterating second list
for(Class2 two : list2){
if(two.isPerformed()){
map.put(two.getID(),two.getName());
}
}
上面的代码工作正常,希望上面的代码使用流来编写。 下面是使用 streams() 的示例代码。
map = list1.stream().filter(one.isStatus()).collect(toMap(lst1 -> lst1.getID(), lst1.getName());
map = list2.stream().filter(...);
但是“地图”在使用 stream() 编写时没有给出预期的结果API。
我不确定您没有看到什么预期结果,但我创建了一个最小的工作示例,您应该能够根据自己的用例进行调整。
public class Main {
public static void main(String[] args) {
List<Person> personList = new ArrayList<>();
Map<Integer, String> personMap = personList.stream()
.filter(Person::isStatus)
.collect(Collectors.toMap(person -> person.id, person -> person.name));
}
private static class Person {
public String name;
public int id;
public boolean isStatus() {
return true;
}
}
}
试试这个,
List<Class1> list1;
List<Class2> list2;
Map<String, String> map1 = list1.stream().filter(Class1::isStatus).collect(Collectors.toMap(Class1::getId, Class1::getName));
Map<String, String> map2 = list2.stream().filter(Class2::isPerformed).collect(Collectors.toMap(Class2::getId, Class2::getName));
map1.putAll(map2);
这里可以应用流连接Stream.concat
以避免map.putAll
Map<String, String> map = Stream.concat(
list1.stream()
.filter(Class1::isStatus)
.map(obj -> Arrays.asList(obj.getID(), obj.getName())),
list2.stream()
.filter(Class2::isPerformed)
.map(obj -> Arrays.asList(obj.getID(), obj.getName()))
) // Stream<List<String>>
.collect(Collectors.toMap(
arr -> arr.get(0), // key - ID
arr -> arr.get(1),
(v1, v2) -> v1 // keep the first value in case of possible conflicts
));
上面的代码使用了一个合并函数(v1, v2) -> v1
来处理当同一个ID在list1
and/orlist2
中多次出现时可能发生的冲突,以保持第一个出现。
但是,以下合并函数允许将所有出现的事件合并为一个字符串值 (v1, v2) -> String.join(", ", v1, v2)
。