sirve settitle que para java collections guava

para que sirve settitle en java



¿Combina múltiples colecciones en una sola colección lógica? (5)

Supongamos que tengo un número constante de colecciones (por ejemplo, 3 ArrayLists) como miembros de una clase. Ahora, quiero exponer todos los elementos a otras clases para que simplemente puedan iterar sobre todos los elementos (idealmente, solo lectura). Estoy usando colecciones de guayaba y me pregunto cómo podría usar iterables / iteradores de guayaba para generar una vista lógica en las colecciones internas sin hacer copias temporales.


Aquí está mi solución para eso:

EDITAR - cambió el código un poco

public static <E> Iterable<E> concat(final Iterable<? extends E> list1, Iterable<? extends E> list2) { return new Iterable<E>() { public Iterator<E> iterator() { return new Iterator<E>() { protected Iterator<? extends E> listIterator = list1.iterator(); protected Boolean checkedHasNext; protected E nextValue; private boolean startTheSecond; public void theNext() { if (listIterator.hasNext()) { checkedHasNext = true; nextValue = listIterator.next(); } else if (startTheSecond) checkedHasNext = false; else { startTheSecond = true; listIterator = list2.iterator(); theNext(); } } public boolean hasNext() { if (checkedHasNext == null) theNext(); return checkedHasNext; } public E next() { if (!hasNext()) throw new NoSuchElementException(); checkedHasNext = null; return nextValue; } public void remove() { listIterator.remove(); } }; } }; }


Plain Java 8 soluciones usando un Stream .

Número constante

Suponiendo private Collection<T> c, c2, c3 .

Una solución:

public Stream<T> stream() { return Stream.concat(Stream.concat(c.stream(), c2.stream()), c3.stream()); }

Otra solución:

public Stream<T> stream() { return Stream.of(c, c2, c3).flatMap(Collection::stream); }

Número de variable

Suponiendo private Collection<Collection<T>> cs :

public Stream<T> stream() { return cs.stream().flatMap(Collection::stream); }


Puede crear una nueva List y addAll() de sus otras List . A continuación, devuelve una lista no modificable con Collections.unmodifiableList() .


Si está utilizando al menos Java 8, vea mi otra respuesta .

Si ya está usando Google Guava, vea la respuesta de Sean Patrick Floyd .

Si está atrapado en Java 7 y no quiere incluir Google Guava, puede escribir su propio (solo lectura) Iterables.concat() usando no más que Iterable e Iterator :

Número constante

public static <E> Iterable<E> concat(final Iterable<? extends E> iterable1, final Iterable<? extends E> iterable2) { return new Iterable<E>() { @Override public Iterator<E> iterator() { return new Iterator<E>() { final Iterator<? extends E> iterator1 = iterable1.iterator(); final Iterator<? extends E> iterator2 = iterable2.iterator(); @Override public boolean hasNext() { return iterator1.hasNext() || iterator2.hasNext(); } @Override public E next() { return iterator1.hasNext() ? iterator1.next() : iterator2.next(); } }; } }; }

Número de variable

@SafeVarargs public static <E> Iterable<E> concat(final Iterable<? extends E>... iterables) { return concat(Arrays.asList(iterables)); } public static <E> Iterable<E> concat(final Iterable<Iterable<? extends E>> iterables) { return new Iterable<E>() { final Iterator<Iterable<? extends E>> iterablesIterator = iterables.iterator(); @Override public Iterator<E> iterator() { return !iterablesIterator.hasNext() ? Collections.emptyIterator() : new Iterator<E>() { Iterator<? extends E> iterableIterator = nextIterator(); @Override public boolean hasNext() { return iterableIterator.hasNext(); } @Override public E next() { final E next = iterableIterator.next(); findNext(); return next; } Iterator<? extends E> nextIterator() { return iterablesIterator.next().iterator(); } Iterator<E> findNext() { while (!iterableIterator.hasNext()) { if (!iterablesIterator.hasNext()) { break; } iterableIterator = nextIterator(); } return this; } }.findNext(); } }; }


Con Guava, puede usar Iterables.concat(Iterable<T> ...) , crea una vista en vivo de todos los iterables, concatenado en uno (si cambia los iterables, la versión concatenada también cambia). A continuación, ajuste la iteración concatenada con Iterables.unmodifiableIterable(Iterable<T>) (no había visto antes el requisito de solo lectura).

Desde Iterables.concat( .. ) JavaDocs:

Combina múltiples iterables en un solo iterable. El iterable devuelto tiene un iterador que atraviesa los elementos de cada iterable en las entradas. Los iteradores de entrada no son consultados hasta que sea necesario. El iterador iterable devuelto admite remove() cuando el iterador de entrada correspondiente lo admite.

Si bien esto no dice explícitamente que se trata de una vista en vivo, la última oración implica que es (que admite el método Iterator.remove() solo si el iterador de respaldo lo admite no es posible a menos que se use una vista en vivo)

Código de muestra:

final List<Integer> first = Lists.newArrayList(1, 2, 3); final List<Integer> second = Lists.newArrayList(4, 5, 6); final List<Integer> third = Lists.newArrayList(7, 8, 9); final Iterable<Integer> all = Iterables.unmodifiableIterable( Iterables.concat(first, second, third)); System.out.println(all); third.add(9999999); System.out.println(all);

Salida:

[1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 9999999]

Editar:

A pedido de Damian, aquí hay un método similar que devuelve una vista de colección en vivo

public final class CollectionsX { static class JoinedCollectionView<E> implements Collection<E> { private final Collection<? extends E>[] items; public JoinedCollectionView(final Collection<? extends E>[] items) { this.items = items; } @Override public boolean addAll(final Collection<? extends E> c) { throw new UnsupportedOperationException(); } @Override public void clear() { for (final Collection<? extends E> coll : items) { coll.clear(); } } @Override public boolean contains(final Object o) { throw new UnsupportedOperationException(); } @Override public boolean containsAll(final Collection<?> c) { throw new UnsupportedOperationException(); } @Override public boolean isEmpty() { return !iterator().hasNext(); } @Override public Iterator<E> iterator() { return Iterables.concat(items).iterator(); } @Override public boolean remove(final Object o) { throw new UnsupportedOperationException(); } @Override public boolean removeAll(final Collection<?> c) { throw new UnsupportedOperationException(); } @Override public boolean retainAll(final Collection<?> c) { throw new UnsupportedOperationException(); } @Override public int size() { int ct = 0; for (final Collection<? extends E> coll : items) { ct += coll.size(); } return ct; } @Override public Object[] toArray() { throw new UnsupportedOperationException(); } @Override public <T> T[] toArray(T[] a) { throw new UnsupportedOperationException(); } @Override public boolean add(E e) { throw new UnsupportedOperationException(); } } /** * Returns a live aggregated collection view of the collections passed in. * <p> * All methods except {@link Collection#size()}, {@link Collection#clear()}, * {@link Collection#isEmpty()} and {@link Iterable#iterator()} * throw {@link UnsupportedOperationException} in the returned Collection. * <p> * None of the above methods is thread safe (nor would there be an easy way * of making them). */ public static <T> Collection<T> combine( final Collection<? extends T>... items) { return new JoinedCollectionView<T>(items); } private CollectionsX() { } }