Such feature is discussed by JDK developers (see JDK-8072723) and might be included in Java-9 (though not guaranteed). The StreamEx library developed by me already has such feature, so you can use it:
List<MyObject> distinct = StreamEx.of(listA).append(listB)
.distinct(MyObject::getFoo).toList();
The StreamEx
class is an enhanced Stream
which is completely compatible with JDK Stream, but has many additional operations including distinct(Function)
which allows you to specify key extractor for distinct operation. Internally it's pretty similar to the solution proposed by @fge.
You can also consider writing custom collector which will combine getting distinct objects and storing them to list:
public static <T> Collector<T, ?, List<T>> distinctBy(Function<? super T, ?> mapper) {
return Collector.<T, Map<Object, T>, List<T>> of(LinkedHashMap::new,
(map, t) -> map.putIfAbsent(mapper.apply(t), t), (m1, m2) -> {
for(Entry<Object, T> e : m2.entrySet()) {
m1.putIfAbsent(e.getKey(), e.getValue());
}
return m1;
}, map -> new ArrayList<>(map.values()));
}
This collector intermediately collects the results into Map<Key, Element>
where Key is the extracted Key and Element is the corresponding stream element. To make sure that exactly first occurring element will be preserved among all repeating ones, the LinkedHashMap
is used. Finally you just need to take the values()
of this map and dump them into the list. So now you can write:
List<MyObject> distinct = Stream.concat(listA.stream(), listB.stream())
.collect(distinctBy(MyObject::getFoo));
If you don't care whether the resulting collection is list or not, you can even remove the new ArrayList<>()
step (just using Map::values
as a finisher). Also more simplifications are possible if you don't care about order:
public static <T> Collector<T, ?, Collection<T>> distinctBy(Function<? super T, ?> mapper) {
return Collector.<T, Map<Object, T>, Collection<T>> of(HashMap::new,
(map, t) -> map.put(mapper.apply(t), t),
(m1, m2) -> { m1.putAll(m2); return m1; },
Map::values);
}
Such collector (preserving the order and returning the List
) is also available in StreamEx library.