Given the following example class:
class Foo{
    String name;
    int value;
    public Foo(String name, int value) {
        this.name = name;
        this.value = value;
    }
    // getters, setters, toString & equals
}
and a list of foos:
List<Foo> fooList = List.of(new Foo("A",1), new Foo("A",2),
                                new Foo("B",1),
                                new Foo("C",1),
                                new Foo("D",1), new Foo("D",2), new Foo("D",3)
                            );
I want to get a list of foos distinct by name and if there are more than one Foos I want to keep the one with the highst value. 
I've found this java-8-distinct-by-property question to get elemnts of the list distinct by name, which uses this method to get distinct elements:
public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
    Set<Object> seen = ConcurrentHashMap.newKeySet();
    return t -> seen.add(keyExtractor.apply(t));
}
I use it like:
fooList.stream().filter(distinctByKey(Foo::getName)).collect(Collectors.toList());
It works to get distinct elements but keeps the first element in the list if there are two or more with the same name and I'am not able to add a condition to keep the one with the highst value.
Another option is to use grouping by:
Map<String,List<Foo>> map = fooList.stream().collect(Collectors.groupingBy(f -> f.getName()));
Here I don't know how to collect the Foos with the highst value from the map to a list.
With the first approach I get:
Foo{name=A, value=1}
Foo{name=B, value=1}
Foo{name=C, value=1}
Foo{name=D, value=1}
With the second:
A=[Foo{name=A, value=1}, Foo{name=A, value=2}]
B=[Foo{name=B, value=1}]
C=[Foo{name=C, value=1}]
D=[Foo{name=D, value=1}, Foo{name=D, value=2}, Foo{name=D, value=3}]
How can I get a list of:
Foo{name=A, value=2}
Foo{name=B, value=1}
Foo{name=C, value=1}
Foo{name=D, value=3}
 
     
    