2009-11-15 10 views
5

¿Hay una clase que representa la concatenación de una colección con otra colección? Esta clase debe ser una Colección en sí misma, y ​​debe delegar todos los métodos a las colecciones subyacentes (internas); no se debe asignar memoria adicional, ni se debe modificar ninguna de las colecciones originales.Una colección que representa una concatenación de dos colecciones en Java

Ejemplo de uso:

Collection<String> foo = ... 
Collection<String> bar = ... 

// this should be O(1) memory and time 
Collection<String> combined = concat(foo, bar); 

if (combined.contains("Zee")) 
    ... 

for (String str : combined) 
    System.out.println(str); 
+0

¿Quiere decir algo así como lo que itertools de Python proporciona? –

+0

en realidad no es claro si quieres una clase que representa una colección y un elemento, dos colecciones o qué .. – Jack

+0

Una clase que representa la concatenación de dos colecciones. – ripper234

Respuesta

0

no estoy seguro de lo que su venta. Mi interpretación de su pregunta es que está buscando el método de agregar en la Colección. Aunque no creo que sea eso lo que estás preguntando.

+0

Busco una colección que encapsula la concatenación de dos colecciones, _without_ la asignación de una cantidad significativa de memoria o la modificación de las colecciones originales. – ripper234

4

Su pregunta es muy vaga. Especialmente "con otro elemento otra colección" no está claro.

Puede al menos agregar el contenido de Collection al Collection actual usando Collection#addAll(). Aquí Collection puede ser cualquiera de sus subinterfaces/implementaciones, p. List o Set.

Ejemplo:

List<String> foos = Arrays.asList("foo1", "foo2", "foo3"); 
List<String> bars = Arrays.asList("bar1", "bar2", "bar3"); 
foos.addAll(bars); // Now foos contains everything. 

Editar: O es que realmente desea crear una nueva Collection basado en una ya existente Collection y luego añadir un nuevo elemento a la misma? En este caso, simplemente construya un nuevo Collection con el Collection existente como argumento de constructor. Ej .:

List<String> foos = Arrays.asList("foo1", "foo2", "foo3"); 
List<String> bars = new ArrayList<String>(foos); 
bars.add("bar"); // Now bars contains everything. 
+0

Siempre prefiero las formas nativas de las bibliotecas de Java para hacer las cosas antes de ir a una biblioteca de terceros. –

2

Creo que lo que está pidiendo es una construcción de Java que le permite poner colecciones juntas sin modificar las colecciones originales. En otras palabras, tiene colecciones A y B, ambas de tamaño N y M respectivamente. Después de la llamada concat, todavía tienes las colecciones A y B y sus tamaños siguen siendo N y M, sin embargo, también tienes la colección C, que apunta a A y B, haciendo su tamaño N + M.

La respuesta es no, Java no tiene nada fuera de la caja que hace esto ... Sin embargo, podría escribir un contenedor rápido que envuelva una serie de colecciones y agregar esas colecciones a la misma. (Todo lo que haría es mantener referencias a cada una de las colecciones) y podría exponer los métodos get/insert según sea necesario.

+0

Eso es precisamente lo que estoy buscando ... me preguntaba si existe tal biblioteca. – ripper234

9

Como siempre para cualquier cosa de colecciones, mira google-collections. Si tiene Set s, específicamente (no sólo una colección general), que desea:

Set<String> combined = Sets.union(foo, bar); 

que crea una vista inmodificable de los dos conjuntos. Es decir, los cambios en foo o bar se reflejarán en combined (pero combined.add() etc. no es compatible).

Para el caso más genérico, que tienen Iterables.concat() sino que simplemente le permite repetir el elemento unido, la interfaz Iterable, obviamente, no incluye contains por lo que está un poco regado allí.

Los otros Colecciones Utilidades clases en Google-colecciones (com.google.common.collect.Lists y com.google.common.collect.Collections2) no contienen ningún métodos de concatenación. No veo por qué no pudieron, pero por el momento no lo hacen.

+4

Descubrimos que el 99% de las veces, los usuarios solo necesitaban iterar. De ahí Iterables.concat(). Internamente también tenemos un Lists.concat() pero cualquiera lo usa, y la mayoría de los que lo hacen podrían haber usado el otro de todos modos. –

3

No hay, pero escribir por sí mismo debería ser sencillo

package ch.akuhn.util; 

import java.util.Iterator; 
import java.util.NoSuchElementException; 

public class Concat { 

    public static <T> Iterable<T> all(final Iterable<T>... iterables) { 
     return new Iterable<T>() { 
      @Override 
      public Iterator<T> iterator() { 
       return new Iterator<T>() { 
        Iterator<Iterable<T>> more = Arrays.asList(iterables).iterator(); 
        Iterator<T> current = more.hasNext() ? more.next().iterator() : null; 
        @Override 
        public boolean hasNext() { 
         if (current == null) return false; 
         if (current.hasNext()) return true; 
         current = more.hasNext() ? more.next().iterator() : null; 
         return this.hasNext(); 
        } 

        @Override 
        public T next() { 
         if (!hasNext()) throw new NoSuchElementException(); 
         return current.next(); 
        } 

        @Override 
        public void remove() { 
         throw new UnsupportedOperationException(); 
        } 
       }; 
      } 
     }; 
    } 

} 

Y luego

for (Object each: Concat.all(collection,whatever,etcetera,...)) { 
    // ... 
} 

acaba de escribir el código aquí, compilar a su propio riesgo!

PS, si usted Análisis de la unidad de escritura gonna de esta clase, enviar 'em para mí.

Cuestiones relacionadas