I'd like to update items in an existing list from an incoming list.
class Person{
String id;
String name;
String age;
.
.
.
@Override
public boolean equals(Object object) {
return ... ((Person) object).id.equals(this.id);
}
}
The current list is shorter:
ArrayList<Person> currentList = Arrays.asList(
new Person("0", "A", 25),
new Person("1", "B", 35)
);
The received list is bigger, eg
ArrayList<Person> updatedList = Arrays.asList(
new Person("0", "X", 99),
new Person("1", "Y", 100),
new Person("2", "C", 2),
new Person("3", "D", 3),
new Person("4", "E", 5)
);
including the items(identified by their id ) from current list.
I'd like to replace all the items in the current list, with the same one's from new list.
So after transformation, current list will be
{ Person(0, "X", 99), Person(1, "Y", 100) }
Is it possible to do with Stream only.
If the currentList
is always a subset of the updatedList
- means that all the currentList
will appear in the updatedList
, you can do the following:
Set<String> setOfId = currentList.stream()
.map(person -> person.getId()) // exctract the IDs only
.collect(Collectors.toSet()); // to Set, since they are unique
List<Person> newList = updatedList.stream() // filter out those who don't match
.filter(person -> setOfId.contains(person.getId()))
.collect(Collectors.toList());
If the updatedList
and currentList
differ significantly - both can have unique persons, you have to do the double iteration and use Stream::map
to replace the Person
. If not found, replace with self:
List<Person> newList = currentList.stream()
.map(person -> updatedList.stream() // map Person to
.filter(i -> i.getId().equals(person.getId())) // .. the found Id
.findFirst().orElse(person)) // .. or else to self
.collect(Collectors.toList()); // result to List
Assuming that you want the currentList item to be replaced by the object from the updatedList the following should work:
currentList.stream().map((p) -> {
return updatedList.stream().filter(u -> p.equals(u)).findFirst().orElse(p);
}).collect(Collectors.toList());
Yes it is possible using stream,
filter record having ids in first list
List<String> ids = currentList.stream().map(Person::getId).collect(Collectors.toList()); currentList = updatedList.stream().filter(o -> ids.contains(o.getId())) .collect(Collectors.toList());
This will achieve what you are asking.
Map<String, Person> collect = updatedList
.stream()
.collect(Collectors.toMap(Person::getId, Function.identity()));
currentList = currentList
.stream()
.map(Person::getId)
.map(collect::get)
.collect(Collectors.toList());
As @Holger mentioned, doing this for a small List is not so elegant
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.