You can stream the List<Age> inside the iterating the items of List<Employee>:
list1.forEach(e -> e.setAge(
list2.stream() // Stream<Age>
.filter(a -> a.getName().equals(e.getName())) // ... find the name match
.map(Age::getAge) // ... extract the age
.findAny().orElse("unknown"))); // ... return it or else "unknown"
- In case there is found no match of names, the default value is set to
unknown.
- Also, you have to assure there are no duplicated names on which the age is based on.
- The age is
String - is it okay?
- Are you sure there are no
null values?
In case you want to remove such unmatched entries, I suggest you use rather Iterator with Map<String, List<Age>>:
Map<String, List<Age>> map = list2.stream()
.collect(Collectors.groupingBy( // Map<String, List<Age>>
Age::getName)); // ... where 'name' is the key
final Iterator<Employee> iterator = list1.iterator();
while (iterator.hasNext()) { // Iterating List<Employee>
final Employee e = iterator.next(); // Employee
if (map.containsKey(e.getName())) { // If there is Age with equal 'name'
final String age = map.get(e.getName()) // ... get the first found age
.get(0).getAge();
e.setAge(age); // ... set it to the Employee
} else iterator.remove(); // ... or else remove the Employee
}
Again care about the points I listed above. Moreover, if you don't want to use the first found age map.get(e.getName()).get(0).getAge(), you need to perform Stream::reduce over the Stream<Age> like:
// null doesn't occurunless the Age::getAge returns null
// The reducing would be much easier if the age is int
// Feel free to find max/min of the ages... up to you
String age = map.get(e.getName()).stream().map(Age::getAge).reduce(...).orElse(null);
Conclusion: The java-stream way is a but clumsy and I, personally, would stick with the procedural for-loop approach.