Strumienie JAVA

0

Witam serdecznie to mój pierwszy post także proszę o wyrozumiałość.

Zacznę od razu na temat.

Mam problem ze zrozumieniem strumieni w Java. Opowiem na przykładzie:

Mam mapę w której znaduje się klient oraz lista produktów zakupionych przez niego i chciałbym wyznaczyć klienta, który zapłacił najwięcej za zakupy.

Zrobiłem coś takiego (chodzi jedynie o wskazówki co ja tu robię źle):

public static void largestPrice (Map<Client, List<ProductFactory>> map){

    Client c = map.entrySet()
            .stream()   // tutaj rozumiem, że znajduję sie w mapie
            .sorted(p -> p.getValue()
                    .stream() // a tutaj w secie produktów
                    .reduce((p1,p2) -> p1.getPrice().add(p2.getPrice()))) //jest dostęp do ceny, ale jest komunikat "Bad return type in lamba expression: BigDecimal cannot be convertet to Product.
            .findFirst()
            .orElseThrow(new NullPointerException("..."))
            .getKey();

}

Dzięki za wskazówki.

2

Zamiast zrobić sorted wykorzystaj funkcje max, tam przekaż Comparator, moższ wykorzystać metodę comparing i przekazac tam funkcje która wyciągnie z EntrySet wartośc ceny,
Ale ja na twoim miejscu ogarnął jakiś tutorial do lambd i strumieni :)

Edit:
wydzielaj tez to osobnych metod, np. zrób metodę która zliczy sumę cen i przekaż jako method reference, bo to co napisałes jest dosyć nieczytelne

0

Jeśli takowe znasz i polecasz byłbym wdzięczny gdybyś podał jakieś źródła. Z google czytałem wiele tematów w tej kwestii tylko naturalną rzeczą jest, że wszystkich przypadków nie da się opisać.

Dzięki za podpowiedź odnośnie funkcji max. Jednak nadal mam problem co potem.

Walczę dalej

1

Samo czytanie poradników w przypadku strumieniów jest bez sensu :). Nie jest istotne źródło (bo i tak większość tutoriali ze streamów zawiera najważniejsze: map, flatMap, filter i collect + dodatki w stylu sorted, sum, min, max, reduce), tylko samodzielne przerobienie tych przykładów. Po prostu sprawdzasz przykład i próbujesz zrobić to samo, żeby mieć takie wyjście jak w przykładzie. Jak długo siedzisz i na nic nie wpadasz to sprawdzasz odpowiedź i próbujesz zrozumieć.
Wiadomo, że wszystkich przypadków nie ma, bo streamy trzeba po prostu zrozumieć (jak przepływają te dane i wtedy jest dużo łatwiej), a zrozumieć da się jedynie przez próbowanie. Mi bardzo ułatwiło stopniowe wyobrażanie sobie tego co mamy na wyjściu i tworzenie takiego "wodospadu" i na każdym poziomie zastanawiam się jakie jest wyjście streama i decyduję co robić dalej.

0

Dlatego teraz siedzę i próbuje. Mam świadomość jednak tego, że czasami jestem mega blisko, a zabraknie mi jednego polecania i wszystko szlak trafia. Jak napisałeś trening i jeszcze raz trening.

Dzięki za wskazówki

1

@kjdeveloper247: w książce "Core Java for the Impatient" lambdy i strumienie są bardzo dobrze wytłumaczone + masz dużo ćwiczeń do zrobienia na to.

1
kjdeveloper247 napisał(a):

Witam serdecznie to mój pierwszy post także proszę o wyrozumiałość.

Zacznę od razu na temat.

Mam problem ze zrozumieniem strumieni w Java. Opowiem na przykładzie:

Mam mapę w której znaduje się klient oraz lista produktów zakupionych przez niego i chciałbym wyznaczyć klienta, który zapłacił najwięcej za zakupy.

Zrobiłem coś takiego (chodzi jedynie o wskazówki co ja tu robię źle):

public static void largestPrice (Map<Client, List<ProductFactory>> map){

    Client c = map.entrySet()
            .stream()   // tutaj rozumiem, że znajduję sie w mapie
            .sorted(p -> p.getValue()
                    .stream() // a tutaj w secie produktów
                    .reduce((p1,p2) -> p1.getPrice().add(p2.getPrice()))) //jest dostęp do ceny, ale jest komunikat "Bad return type in lamba expression: BigDecimal cannot be convertet to Product.
            .findFirst()
            .orElseThrow(new NullPointerException("..."))
            .getKey();

}

Dzięki za wskazówki.

Odpowiedź, jest bardzo prosta:
Zajrzyj do dokumentacji metody reduce. Zwraca ona obiekt typu T. Czyli w twoim przypadku musisz zwrócić to co wchodzi, czyli 'Product'. Tymczasem ty zwracasz BigDecimal, który jest wynikiem działania metody add.

PS:
Nawiasem mówiąc przemyśl, czy poprawnie implementujesz komparator. Przypuszczam, że cena zawsze jest dodatnia. Dodawanie dwóch dodatnich cen będzie zawsze dodatnie, wynikiem czego p1 będzie zawsze większe od p2, niezależnie od wartości (poza sytuacją, gdzie przeskoczysz inta). W komparatorze zwracasz nie liczbę, która potem służy do porównywania, tylko liczbę, która świadczy o wyniku porówniania. Nie ma znaczenia czy będzie to 1, czy 1500100900

1 użytkowników online, w tym zalogowanych: 0, gości: 1