假设我有一个非常简单的类Person,其中包含名称和地址:
public class Person {
String name;
String address;
public Person(final String name,
final String address) {
this.name = name;
this.address = address;
}
public String getName() {
return name;
}
public void setName(final String newName) {
this.name = newName;
}
public String address() {
return address;
}
public void setAddress(final String newAddress) {
this.address = newAddress;
}
}
我现在有一个Set,其中包含所有已知的Person对象,并且我只想根据一个人的名字来更新其中一个人的地址。为此,我有以下内容:
persons.stream()
.filter(person -> personToUpdate.getName().equalsIgnoreCase(person.getName()))
.forEach(person -> {
person.setAddress(personToUpdate.getAddress());
});
但是,我的问题是当我有一个完全不在集合中的新人时。我如何检查“设置”以查看此人是否存在,如果存在,请更新其地址。但是,如果它们不存在,请将其添加到列表中。我知道这很简单,但是出于任何原因,我都无法立即考虑如何实现这一目标。我不想走一个创建所有名称的列表,比较新名称,如果它们在列表中的情况,等等,等等。我宁愿保持简洁。
编辑:名称将是唯一的!
答案 0 :(得分:4)
除非您需要单线,否则您可以简单地利用Optional
的优势:
Optional<Person> person = persons.stream()
.filter(p -> personToUpdate.getName().equalsIgnoreCase(p.getName()))
.findFirst();
if (person.isPresent()) {
person.get().setAddress(personToUpdate.getAddress());
} else {
persons.add(personToUpdate);
}
如果您使用的是Java 9+,这看起来会更好:
persons.stream()
.filter(p -> personToUpdate.getName().equalsIgnoreCase(p.getName()))
.findFirst()
.ifPresentOrElse(
p -> p.setAddress(personToUpdate.getAddress()),
() -> persons.add(personToUpdate)
);
这当然假定名称是唯一的(因为您希望更新一个条目)。
答案 1 :(得分:1)
您可以通过使用Map
来做到这一点。
Map<String, Person> personMap = persons.stream()
.collect(Collectors.toMap(Person::getName, Function.identity()));
personMap.merge(personToUpdate.getName(), personToUpdate,
(p1, p2) -> new Person(p1.getName(), p2.address()));
答案 2 :(得分:0)
有几种简单的方法可以做到这一点(我假设名称唯一地标识一个Person,并且两个具有相同名称的Person对象被视为相等)
equals
和hashcode
,并在流之前进行contains
调用-如果返回false,则不在集合中Map
代替Set
,在这里可以轻松地通过属性(例如名称,在这里似乎是您的主键)使用该键来查找人。旁注-无论如何都应实现equals
和hashcode
-尤其是将这些对象放入Set
或Map
中时。通过实现equals
和hashcode
仅考虑名称,您将保证名称在集合中的唯一性(目前无法保证)
答案 3 :(得分:0)
假设(1)您的Person
对象仅打算使用引用相等进行比较(因此需要保留对象标识),并且(2)多个Person
对象可能与一个给定名称,您将需要手动处理以下情况:
public static void updatePersonAddress(String name, String address, Set<Person> persons) {
// Find all the matching persons, if any.
List<Person> matched = new ArrayList<>();
for (Person person : persons) {
if (person.getName().equalsIgnoreCase(name)) {
matched.append(person);
}
}
// If zero persons matched, create a new Person to match,
// and add the new person to the set. Then we're done!
if (matched.isEmpty()) {
persons.add(new Person(name, address));
return;
}
// Otherwise, update the Person objects (which are still in the
// persons Set) to include the new address.
for (Person person : matched) {
person.setAddress(address);
}
}
如果名称是唯一的,则简化为:
public static void updatePersonAddress(String name, String address, Set<Person> persons) {
for (Person person : persons) {
if (person.getName().equalsIgnoreCase(name)) {
person.setAddress(address);
// If we've found one that matches, then we know there
// won't be any more, so we can be done now.
return;
}
}
// If we made it through the loop without returning, then it means
// that no Person in the Set matched. So add one that does.
persons.add(new Person(name, address));
}
答案 4 :(得分:0)
您可以使用person.contains(person)。但是,您将不得不重写hashcode()和equals()方法