Załóżmy, że mam stałą liczbę kolekcji (np. 3 ArrayLists) jako członków klasy. Teraz chcę ujawnić wszystkie elementy innym klasom, aby mogły po prostu iterować po wszystkich elementach (najlepiej tylko do odczytu). Używam kolekcji guawy i zastanawiam się, jak mógłbym użyć iteracji / iteratorów guawy, aby wygenerować logiczny widok na wewnętrzne kolekcje bez tworzenia tymczasowych kopii.
java
collections
guava
newgre
źródło
źródło
Odpowiedzi:
Dzięki Guava, możesz użyć
Iterables.concat(Iterable<T> ...)
, tworzy widok na żywo wszystkich iterowalnych, połączonych w jedną (jeśli zmienisz iterowalne, połączona wersja również się zmieni). Następnie zawiń połączoną iterację zIterables.unmodifiableIterable(Iterable<T>)
(nie widziałem wcześniej wymagania tylko do odczytu).Z
Iterables.concat( .. )
JavaDocs:Chociaż nie oznacza to wyraźnie, że jest to podgląd na żywo, ostatnie zdanie sugeruje, że tak jest (obsługa
Iterator.remove()
metody tylko wtedy, gdy iterator wspierający obsługuje, nie jest możliwa, chyba że używa się podglądu na żywo)Przykładowy kod:
Wynik:
Edytować:
Na żądanie od Damiana, oto podobna metoda, która zwraca aktywny widok kolekcji
źródło
Iterables.unmodifiableIterable(iterable)
Iterables.concat
produkujeIterable
, nieCollection
. PotrzebowałbymCollection
widoku.size()
to jest to, czego potrzebuję.add()
rzucenie wyjątku jest dobre - nie obchodzi mnie ta metoda. Collection API jest zepsuta i nikt nie może nic na to poradzić.Collection.add()
,Iterator.remove()
bla.Zwykłe rozwiązania Java 8 wykorzystujące rozszerzenie
Stream
.Stała liczba
Zakładając
private Collection<T> c, c2, c3
.Jedno rozwiązanie:
Inne rozwiązanie:
Zmienna liczba
Zakładając
private Collection<Collection<T>> cs
:źródło
Jeśli używasz przynajmniej Java 8, zobacz moją drugą odpowiedź .
Jeśli korzystasz już z Google Guava, zobacz odpowiedź Seana Patricka Floyda .
Jeśli utknąłeś w Javie 7 i nie chcesz dołączać Google Guava, możesz napisać własną (tylko do odczytu),
Iterables.concat()
używając nie więcej niżIterable
iIterator
:Stała liczba
Zmienna liczba
źródło
Możesz stworzyć nowe
List
iaddAll()
swoje inneList
. Następnie zwróć niemodyfikowalną listę za pomocąCollections.unmodifiableList()
.źródło
ArrayList
po prostu przydziela miejsce i wywołaniaSystem.arraycopy()
pod maską. Nie można być bardziej wydajnym niż to.Oto moje rozwiązanie:
EDYCJA - trochę zmienił kod
źródło
hasNext()
inext()
. Pierwsza zmienia stan twojego iteratora, a druga nie. Powinno być na odwrót. Wołanienext()
bez wołaniahasNext()
zawsze ustąpinull
. WywołaniehasNext()
bez wywołanianext()
spowoduje odrzucenie elementów. Twójnext()
też nie rzucaNoSuchElementException
, ale wracanull
.