Chcę podsumować listę liczb całkowitych. Działa w następujący sposób, ale składnia nie wydaje się właściwa. Czy można zoptymalizować kod?
Map<String, Integer> integers;
integers.values().stream().mapToInt(i -> i).sum();
java
java-8
java-stream
Membersound
źródło
źródło
mapToLong
aby uniknąć przepełnienia, w zależności od wartości, jakie może mieć mapa.i -> i
bardzo jasne. Cóż, tak, musisz wiedzieć, że wartość zostanie automatycznie rozpakowana, ale jest to prawdą, ponieważ Java 5 ...foo(int i)
, nie piszą zafoo(myInteger.intValue());
każdym razem, gdy ją wywołują (a przynajmniej nie oczekuję !!). Zgadzam się z tobą, coInteger::intValue
jest bardziej wyraźne, ale myślę, że to samo dotyczy tutaj. Ludzie powinni się tego nauczyć raz, a potem skończysz :-). To nie jest tak, jakby to było jakieś magiczne zaciemnienie.i -> i
wygląda na to , że nie ma op, a koncepcyjnie jest to brak op. Jasne, pod maskąInteger.intValue()
zostaje wywołane, ale jeszcze głębiej pod maską, że metody są wprowadzane, aby stać się dokładnie tym, czego nie ma w kodzie źródłowym.Integer::intValue
ma tę zaletę, że nie tworzy syntetycznej metody w kodzie bajtów, ale nie jest to tym, co powinno decydować o sposobie organizacji kodu źródłowego.Odpowiedzi:
To zadziała, ale
i -> i
wykonuje automatyczne rozpakowywanie, dlatego „wydaje się” dziwne. Oba z poniższych sposobów będą działać i lepiej wyjaśnić, co kompilator robi pod maską, używając oryginalnej składni:źródło
BigDecimal sum = numbers.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
Sugeruję jeszcze 2 opcje:
Drugi używa
Collectors.summingInt()
kolektora, jest teżsummingLong()
kolektor, którego można użyćmapToLong
.I trzecia opcja: Java 8 wprowadza bardzo skuteczny
LongAdder
akumulator zaprojektowany w celu przyspieszenia podsumowania w równoległych strumieniach i środowiskach wielowątkowych. Oto przykład użycia:źródło
Z dokumentów
Tak więc dla mapy użyłbyś:
Lub:
źródło
Możesz użyć metody zmniejszania:
lub
źródło
int
, to jestInteger::sum
Long::sum
niżInteger::sum
.Możesz użyć
reduce()
do zsumowania listy liczb całkowitych.źródło
Możesz użyć metody Collect, aby dodać listę liczb całkowitych.
źródło
Byłby to najkrótszy sposób na podsumowanie
int
typu tablica (dlalong
tablicyLongStream
, dladouble
tablicyDoubleStream
i tak dalej).Stream
Jednak nie wszystkie pierwotne typy całkowite lub zmiennoprzecinkowe mają implementację.źródło
IntStream.of()
nie zadziała dla tego problemu, chyba że stworzymy coś tak upiornego:IntStream.of( integers.values().stream().mapToInt( Integer::intValue ).toArray() ).sum();
integers.values().stream().mapToInt( Integer::intValue ).sum()
.Może to pomóc tym, którzy mają obiekty na liście.
Jeśli masz listę obiektów i chcesz zsumować określone pola tego obiektu, skorzystaj z poniższej listy.
źródło
Zadeklarowałem listę liczb całkowitych.
Możesz spróbować użyć tych różnych sposobów poniżej.
Za pomocą
mapToInt
Za pomocą
summarizingInt
Za pomocą
reduce
źródło
źródło
Omówiono większość aspektów. Ale może istnieć wymóg znalezienia agregacji innych typów danych oprócz Integer, Long (dla których już istnieje specjalistyczna obsługa strumienia). Na przykład stram z BigInteger W przypadku takiego typu możemy użyć operacji zmniejszania jak
list.stream (). zmniejsz ((bigInteger1, bigInteger2) -> bigInteger1.add (bigInteger2))
źródło