jeżeli mamy kolekcje a={ a,b,d,v,b,}
jak przygotować strem tak aby znaleźć b i zwrócić kolejny element?
pseudokod :
String r= a.stream.filter(c->c.equals(b)).getNext
jeżeli mamy kolekcje a={ a,b,d,v,b,}
jak przygotować strem tak aby znaleźć b i zwrócić kolejny element?
pseudokod :
String r= a.stream.filter(c->c.equals(b)).getNext
W JDK9 jest takeWhile
, no ale zakładając że kolekcja jest posortowana bo tylko dla niej ma to sens, wystarczy zrobić (ważne!) sekwencyjną redukcję. Akumulatorem jest wartość która przyjmuje trzy wartości - początkową, przejściową oznaczającą że element szukany był przed chwilą redukowany, oraz końcową o wartości znalezionego obiektu. Redukcja polega na tym:
Jeśli na wyjściu dostajesz początkową to szukanego elementu nie ma, jak przejściową to nie ma on następnika, w przeciwnym wypadku dostajesz szukaną wartość. Trzeba trochę pokombinować żeby te markery można wpakować do akumulatora, no ale chcesz funkcyjne rzeczy w Javie, trochę się trzeba namęczyć.
Jeżeli potrzebujesz element po pierwszym wystąpieniu podanego elementu, to można specyficznym reduktorem załatwić:
public class FindNextOnFirst {
public static void main(String[] args) {
List<String> strings = Lists.asList("a", "b", new String[]{"c", "d", "b", "e"});
Optional<String> nextAfter = strings.stream()
.peek(System.out::println)
.map(Optional::of)
.reduce(Optional.empty(),
(l, r) -> {
if(l.isPresent() && l.get().equals("b"))
return r; // next after b
if(!l.isPresent() && r.get().equals("b"))
return r; // current is b
return l;
}
);
System.out.println("Next after b is: " + nextAfter.orElse("Cannot find"));
}
}
Jeżeli dorzucisz Javaslang, to można z tej ifologi zrezygnować na rzecz pattern matchingu.