Szukam sposobu implementacji operacji zgrupowania nieterminowego, tak aby narzut pamięci był minimalny.Strumienie Java - efektywne grupowanie elementów w posortowanych strumieniach
Na przykład rozważ odrębność(). W ogólnym przypadku nie ma innego wyjścia, jak zebrać wszystkie odrębne przedmioty, a dopiero potem przesyłać je dalej. Jednakże, jeśli wiemy, że strumień wejściowy jest już posortowany, operację można wykonać "w locie", używając minimalnej pamięci.
Wiem, że mogę to osiągnąć dla iteratorów za pomocą opakowania iteratora i implementując logikę grupowania. Czy istnieje prostszy sposób zaimplementowania tego przy użyciu API strumieniowego?
- EDIT -
znalazłem drogę do nadużyć Stream.flatMap (..) w celu osiągnięcia to:
private static class DedupSeq implements IntFunction<IntStream> {
private Integer prev;
@Override
public IntStream apply(int value) {
IntStream res = (prev != null && value == prev)? IntStream.empty() : IntStream.of(value);
prev = value;
return res;
}
}
, a następnie:
IntStream.of(1,1,3,3,3,4,4,5).flatMap(new DedupSeq()).forEach(System.out::println);
Która wydruki:
1
3
4
5
Po wprowadzeniu pewnych zmian tę samą technikę można zastosować do dowolnego efektywnego w pamięci grupowania sekwencji strumieni. W każdym razie, nie podoba mi się to rozwiązanie i szukałem czegoś bardziej naturalnego (na przykład sposobu, w jaki działa mapowanie lub filtrowanie). Co więcej, zerwam kontrakt tutaj, ponieważ funkcja dostarczana do flatMap (..) jest stateful.
Zawsze można ".filter (someSet :: add) ', ale czy próbowałeś i porównałeś wydajność takiego rozwiązania ze zwykłym' distinct() '? Mówisz też "w ogólnym przypadku", ale może być tak, że istnieje zoptymalizowana implementacja w przypadku, gdy 'Stream' _is_' ORDERED', właśnie (lub dokładniej, jego bazowy 'Spliterator') – fge
@fge: Nie jestem pewien, czy jest tam jakaś optymalizacja. Kod: IntStream.range (0, 100000000) .distinct(). ForEach (x -> {}); Uruchamia się pamięć, pomimo tego, że leżący u jej podstaw Spliterator zgłasza się jako ORDERED. –
Czy próbowałeś z '.forEachOrdered()'? – fge