java - que - Inicializando un conjunto con un Iterable
iterator java recorrer lista (5)
Esta pregunta ya tiene una respuesta aquí:
- Convertir Iterator a ArrayList 12 respuestas
Quiero inicializar una Implementación de conjunto (HashSet) en Java con un Iterable. Sin embargo, el constructor de HashSet no acepta objetos Iterables, sino solo objetos de tipo Colecciones.
¿Hay alguna manera de convertir de Iterable a algún subtipo de Colecciones?
Claro, se muestra en esta respuesta. Básicamente, itere sobre el iterable y copie su contenido en una colección:
public static <T> List<T> copyIterable(Iterable<T> iterable) {
Iterator<T> iter = iterable.iterator();
List<T> copy = new ArrayList<T>();
while (iter.hasNext())
copy.add(iter.next());
return copy;
}
Úselo de la siguiente manera, el objeto List
resultante se puede pasar como un parámetro al constructor HashSet
.
Iterable<Integer> list = Arrays.asList(1, 2, 3);
List<Integer> copy = copyIterable(list);
Set<Integer> aSet = new HashSet<Integer>(copy);
EDITAR
Estuve equivocado todo el tiempo. Iterable
es una superinterfaz de Collection
, por lo que un elenco simple (pero inseguro) hará el truco, siempre y cuando el Iterable
una Collection
para empezar.
Iterable<Integer> list = Arrays.asList(1, 2, 3);
Set<Integer> aSet = new HashSet<Integer>((Collection)list); // it works!
La interfaz Iterable permite que la sintaxis "foreach" funcione, por lo que la forma más limpia es probable:
public <T> Set<T> toSet(Iterable<T> collection) {
HashSet<T> set = new HashSet<T>();
for (T item: collection)
set.add(item);
return set;
}
Puedes usar guayaba
Set<T> set = Sets.newHashSet(iterable);
o para que se lea como una importación estática de oraciones,
import static com.google.common.collect.Sets.*;
Set<T> set = newHashSet(iterable);
Solo agrega cada uno.
public static <T> Set<T> setFromIterable(Iterable<T> i) {
HashSet<T> set = new HashSet<T>();
Iterator<T> it = i.iterator();
while (it.hasNext()) {
set.add(it.next());
}
return set;
}
Iterable<Integer> someIterable = ...;
Set<Integer> someSet = setFromIterable(someIterable);
Tenga en cuenta que no usa el constructor new HashSet<Integer>(someIterator)
, porque eso no existe. Simplemente llame al método estático.
HashSet
constructor HashSet
basa en más de lo que ofrece Iterable
: quiere saber el size
de la colección por adelantado para construir de manera óptima el HashMap
subyacente. Si tienes una Iterable
verdadera, austera, que no conoce su tamaño, entonces tendrás que realizar el Iterable
al frente convirtiéndolo en una Collection
regular en cualquiera de una serie de formas obvias.
Si, por otro lado, tiene un objeto más rico que ya conoce su tamaño, entonces pagaría crear una clase de adaptador minimalista que envuelva su Iterable
en una colección, implementando solo el size
además de reenviar la llamada al iterator
.
public class IterableCollection<T> implements Collection<T>
{
private final Iterable<T> iterable;
public IterableCollection(Iterable<T> it) { this.iterable = it; }
@Override public Iterator<T> iterator() { return iterable.iterator(); }
@Override public int size() { return ... custom code to determine size ... }
@Override .... all others ... { throw new UnsupportedOperationException(); }
}