Mam strumień obiektów i chciałbym znaleźć ten z maksymalną wartością jakiegoś atrybutu, który jest drogi do wyliczenia.Strumień Java: znajdź element o wartości min/max atrybutu
Jako konkretny prosty przykład, powiedzmy, że mamy listę ciągów znaków i chcemy znaleźć najfajniejszą, biorąc pod uwagę funkcję coolnessIndex
.
Poniższa powinno działać:
String coolestString = stringList
.stream()
.max((s1, s2) -> Integer.compare(coolnessIndex(s1), coolnessIndex(s2)))
.orElse(null);
Teraz istnieją dwa problemy z tym. Po pierwsze, zakładając, że coolnessIndex
jest kosztowny do obliczenia, prawdopodobnie nie będzie to bardzo efektywne. Przypuszczam, że metoda max
będzie musiała wielokrotnie używać komparatora, który z kolei będzie wielokrotnie wywoływał numer coolnessIndex
, a na końcu będzie wywoływany więcej niż raz dla każdego ciągu.
Po drugie, konieczność dostarczenia komparatora prowadzi do pewnej nadmiarowości w kodzie. Chciałbym zdecydowanie wolą składnię tak:
String coolestString = stringList
.stream()
.maxByAttribute(s -> coolnessIndex(s))
.orElse(null);
Jednak nie udało się znaleźć metodę dopasowania w Stream
API. To mnie zaskakuje, ponieważ znalezienie min/maksimum przez atrybut wydaje się być wspólnym wzorcem. Zastanawiam się, czy istnieje lepszy sposób niż użycie komparatora (innego niż pętla for).
Podobne, ale nie całkiem powielać: http://stackoverflow.com/questions/27606185/arg-max-in-java-8-streams (gdzie problemem jest zwięzłość kodu, a nie efektywność, i myślę, że zalecane rozwiązanie wciąż kończy się wywoływaniem odpowiednika "coolnessIndex" wielokrotnie). –
Nie wierzę, że jest coś podobnego w interfejsie API strumieni Java. Możesz zaimplementować własną wersję 'maxByAttribute' (ktoś inny zrobił coś w tym rodzaju [tutaj] (https://gist.github.com/mapio/57299694ef94cc88dddb), ale nie sprawdzałem ich kodu) lub może użyć 'map', aby uzyskać strumień par (' s', 'coolnessIndex (s)'), a następnie 'max', ale Java AIUI nie ma przydatnej klasy pair, więc skończyłoby się na dużo kodu standardowego, nie mówiąc już o wszystkich dodatkowych przydziałach pamięci. –
Możesz grupować według ciągu znaków-> chłód na mapie, a następnie wybrać najfajniejszy ciąg. Zobacz https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html#toMap-java.util.function.Function-java.util.function.Function- –