我正在创建一个地图,其(键,值)在我的Person对象中将是(名称,地址):
Map<String, String> myMap = persons.stream.collect(Collector.toMap(person.getName(), person.getAddress(), (address1, address2) -> address1));
在重复键的情况下,我想跳过将第二个地址添加到地图的操作,并且还要记录名称。跳过重复的地址我已经可以使用mergeFunction来做,但是为了在这个mergeFunction中记录我需要的人对象名称,例如:
(address1, address2) -> {
System.out.println("duplicate "+person.name() + " is found!");
return address1;
}
将人对象传递给此合并功能使我陷入困境。
答案 0 :(得分:6)
@Aomine:解决方案看起来不错,对我也适用。只是想确认一下,这次迭代了两次?像下面这样的简单解决方案的原因仅迭代一次,但达到了要求。
Map<String,String> myMap= new HashMap<>();
persons.stream().foreach(item-> {
if(myMap.containsKey(item.getName()))
{/*do something*/}
else
myMap.put(item.getName(),item.getAddress());
});
答案 1 :(得分:6)
我相信forEach
方法与Map.merge
一起使用会更简单并且适合当前用例:
Map<String, String> myMap = new HashMap<>();
persons.forEach(person -> myMap.merge(person.getName(), person.getAddress(), (adrs1, adrs2) -> {
System.out.println("duplicate " + person.getName() + " is found!");
return adrs1;
}));
注意:Map.merge
也使用BiFunction
(BinaryOperator
中toMap
的父对象),因此您可以在此处关联合并功能轻松地将其转换为现有的所需功能。
答案 2 :(得分:1)
如果要在合并功能中访问整个人员对象,请为Function.identity()
传递valueMapper
:
Map<String, Person> myMap =
persons.stream()
.collect(toMap(p -> p.getName(),
Function.identity(), // or p -> p
(p1, p2) -> { /* do logic */ }));
但是如您所见,如果您仍然希望将Person
作为结果并仍然访问{{1}中的整个Map<String, String>
对象,则生成的映射值为Person
对象},则可以执行以下操作:
mergeFunction
答案 3 :(得分:1)
这是使用peek
import java.util.*;
import java.util.stream.*;
class App {
public static void main(String[] args) {
List<Person> persons = Arrays.asList(new Person("foo", "bar"), new Person("baz", "qux"), new Person("foo", "zuz"));
Set<String> names = new HashSet<>();
Map<String, String> nameAddress = persons.stream().peek(p -> {
if (names.contains(p.getName())) {
System.out.println("Duplicate key being skipped: " + p);
} else {
names.add(p.getName());
}
}).collect(Collectors.toMap(person -> person.getName(), person -> person.getAddress(), (addr1, addr2) -> addr1));
}
}
class Person {
String name;
String address;
public Person(String name, String address) {
this.name = name;
this.address = address;
}
public String getName() {
return name;
}
public String getAddress() {
return address;
}
@Override
public String toString() {
return name + " " + address;
}
}
对我来说,上面的代码段输出如下:
Duplicate key being skipped: foo zuz