Warum brauchen Sie Reflexion, um Faulheit zu bekommen? Betrachten wir zum Beispiel diese Klasse:
class LazySeq<T> {
private final List<T> list;
private Predicate<? super T> predicate;
public LazySeq(List<T> input) {
this.list = new ArrayList<>(input);
}
//Here you just store the predicate, but you don't perform a filtering
//You could also return a new LazySeq with a new state
public LazySeq<T> filter(Predicate<? super T> predicate) {
this.predicate = predicate;
return this;
}
public void forEach(Consumer<? super T> consumer){
if(predicate == null) {
list.forEach(consumer);
} else {
for(T elem : list) {
if(predicate.test(elem)) {
consumer.accept(elem);
}
}
}
}
}
Wenn Sie filter
auf den faulen seq nennen, wird die Filterung nicht sofort passieren, so zum Beispiel:
LazySeq<Integer> lazySeq = new LazySeq<>(Arrays.asList(1, 2, 3, 4));
lazySeq = lazySeq.filter(i -> i%2 == 0);
Wenn Sie sehen den Inhalt der Sequenz nach dem Aufruf Filter, Sie werden sehen, dass es immer 1, 2, 3, 4
ist. Wenn Sie jedoch eine Terminaloperation aufrufen, wie z. B. forEach
, wird die Filterung vor der Verwendung des Verbrauchers durchgeführt. So zum Beispiel:
lazySeq.filter(i -> i%2 == 0).forEach(System.out::println);
2 gedruckt werden und 4.
Dies ist das gleiche Prinzip mit Stream
s. Von einer Quelle führen Sie Operationen aus, die bestimmte Eigenschaften aufweisen. Diese Operationen sind entweder intermediär und geben einen verzögerten Stream zurück (z. B. filter
oder map
) oder terminal (z. B. forEach
). Einige dieser terminalen Operationen sind kurzgeschlossen (wie findFirst
), sodass Sie möglicherweise nicht die gesamte Pipeline durchlaufen (Sie können sich eine frühe Rückgabe in einer for-Schleife vorstellen, die beispielsweise den Index eines Werts in einem Array zurückgibt).
Wenn Sie eine Terminaloperation aufrufen, wird diese Operationskette ausgeführt, sodass Sie am Ende das erwartete Ergebnis erhalten.
Faulheit kann erreicht werden, indem ein neuer Zustand in der Pipeline gespeichert wird, wenn eine Zwischenoperation angewendet wird, und wenn Sie eine Terminaloperation aufrufen, werden alle Zustände nacheinander nach den Daten sortiert.
Die Stream-API ist nicht wirklich so implementiert (es ist ein bisschen komplexer), aber das Prinzip ist wirklich hier.
Ich akzeptierte Alexis Antwort, weil es eine bessere Vorstellung davon gab, wonach ich suchte. Aber die Antwort von HuStmpHrrr sieht raffinierter aus. Danke allen. – Learner