Reputation: 1546
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, e.g.
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.
Upvotes: 4
Views: 11341
Reputation: 765
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());
Upvotes: 0
Reputation: 5463
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());
Upvotes: 1
Reputation: 44398
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
Upvotes: 3
Reputation: 27038
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
Upvotes: 0