Die Aufgabe, die Sie erreichen möchten, unterscheidet sich erheblich von der Gruppierung. groupingBy
verlässt sich nicht auf die Reihenfolge der Stream
Elemente, sondern auf den Map
's-Algorithmus auf den Klassifikator Function
Ergebnis angewendet.
Sie möchten benachbarte Elemente mit einem gemeinsamen Eigenschaftswert in einen List
Artikel falten. Es ist nicht einmal notwendig, die Stream
nach dieser Eigenschaft sortiert zu haben, solange Sie garantieren können, dass alle Elemente mit demselben Eigenschaftswert gruppiert sind.
Vielleicht ist es möglich, diese Aufgabe als eine Reduktion zu formulieren, aber für mich sieht die resultierende Struktur zu kompliziert aus.
Also, es sei denn, direkte Unterstützung für diese Funktion zu den Stream
s hinzugefügt wird, ein Iterator basierten Ansatz pragmatischsten mir aussieht:
class Folding<T,G> implements Spliterator<Map.Entry<G,List<T>>> {
static <T,G> Stream<Map.Entry<G,List<T>>> foldBy(
Stream<? extends T> s, Function<? super T, ? extends G> f) {
return StreamSupport.stream(new Folding<>(s.spliterator(), f), false);
}
private final Spliterator<? extends T> source;
private final Function<? super T, ? extends G> pf;
private final Consumer<T> c=this::addItem;
private List<T> pending, result;
private G pendingGroup, resultGroup;
Folding(Spliterator<? extends T> s, Function<? super T, ? extends G> f) {
source=s;
pf=f;
}
private void addItem(T item) {
G group=pf.apply(item);
if(pending==null) pending=new ArrayList<>();
else if(!pending.isEmpty()) {
if(!Objects.equals(group, pendingGroup)) {
if(pending.size()==1)
result=Collections.singletonList(pending.remove(0));
else {
result=pending;
pending=new ArrayList<>();
}
resultGroup=pendingGroup;
}
}
pendingGroup=group;
pending.add(item);
}
public boolean tryAdvance(Consumer<? super Map.Entry<G, List<T>>> action) {
while(source.tryAdvance(c)) {
if(result!=null) {
action.accept(entry(resultGroup, result));
result=null;
return true;
}
}
if(pending!=null) {
action.accept(entry(pendingGroup, pending));
pending=null;
return true;
}
return false;
}
private Map.Entry<G,List<T>> entry(G g, List<T> l) {
return new AbstractMap.SimpleImmutableEntry<>(g, l);
}
public int characteristics() { return 0; }
public long estimateSize() { return Long.MAX_VALUE; }
public Spliterator<Map.Entry<G, List<T>>> trySplit() { return null; }
}
Der faule Art des Stream
gefalteten resultierenden besten nachgewiesen werden kann, durch die Anwendung es zu einem unendlichen Strom:
Folding.foldBy(Stream.iterate(0, i->i+1), i->i>>4)
.filter(e -> e.getKey()>5)
.findFirst().ifPresent(e -> System.out.println(e.getValue()));
Wie kann du machst ein faules gruppiere nach? Um nach einer Eigenschaft des im Stream enthaltenen Objekts zu gruppieren, müssen Sie über alle Elemente im Stream iterieren. – Eran
Was meinen Sie mit "Gruppierung seiner Linien?" meinst du binning wie die stream 'groupBy' Methode oder meinst du das Lesen mehrerer Zeilen gleichzeitig? – dkatzel
Danke für die Kommentare, ein Update zur Frage hinzugefügt. –