Załóżmy, że mam Collection
i Predicate
pasujący do elementów, które chciałbym usunąć z Collection
. Ale ja nie chcę ich odrzucać, chcę przenieść dopasowane elementy do nowej kolekcji. Chciałbym zrobić coś takiego this w Javie 7:Usuwanie i zbieranie elementów za pomocą strumieni Java
List<E> removed = new LinkedList<>();
for (Iterator<E> i = data.iterator(); i.hasNext();) {
E e = i.next();
if (predicate.test(e)) {
removed.add(e);
i.remove();
}
}
Jestem ciekaw czy istnieje strumienie/Java 8 sposobów, aby to zrobić. Collections.removeIf()
niestety po prostu zwraca boolean
(nawet zliczania liczby elementów usuniętych Zbyt źle?). I wyobrazić sobie coś takiego (choć oczywiście .removeAndYield(Predicate)
nie istnieje):
List<E> removed = data.removeAndYield(predicate).collect(Collectors.toList());
Uwaga: to pytanie inspirowane przez a similar question; to pytanie dotyczy bardziej ogólnego przypadku pobrania strumienia z elementów usuniętych z kolekcji. Jak wskazano w połączonym pytaniu, rozwiązanie imperatywne może być bardziej czytelne, ale jestem ciekawy, czy jest to nawet możliwe w przypadku strumieni.
Edycja: Oczywiście możemy podzielić zadanie na dwa osobne etapy i przy założeniu odpowiednich struktur danych będzie to efektywne. Pytanie może dotyczyć dowolnych kolekcji (które mogą nie być wydajne .contains()
itp.).
Trudność polega na tym, że nie można usunąć elementów z 'Seta' podczas iteracji bez uzyskania' ConcurrentModificationException', więc każda metoda Java 8 wymagałaby co najmniej dwóch iteracji, jak w odpowiedzi Mishy. AFAIK jedynym sposobem na zrobienie tego przy pomocy pojedynczej iteracji 'set' jest użycie jawnego' Iteratora'. –
Możesz za pomocą 'Iteratora' nad' Collection', co sugeruje, że jest to możliwe z koncepcją 'Stream'. Oczywiście nie oznacza to, że jest dostępny po wyjęciu z pudełka, ale może nie jest to skomplikowane. A może jest jakiś dobry powód, dla którego nie jest dostępny w JDK. – dimo414
Przykład "Java 7" w moim pytaniu demonstruje usuwanie elementów w połowie iteracji. Jeśli możemy zrobić to w jednym przebiegu, to czy można to zrobić funkcjonalnie? – dimo414