Tengo una matriz de primitivas, por ejemplo para int, int [] foo. Puede ser pequeño o no.
int foo[] = {1,2,3,4,5,6,7,8,9,0};
¿Cuál es la mejor manera de crear un a Iterable<Integer>
partir de él?
Iterable<Integer> fooBar = convert(foo);
Notas:
No responda con bucles (a menos que pueda dar una buena explicación sobre cómo el compilador hace algo inteligente al respecto).
También tenga en cuenta que
int a[] = {1,2,3};
List<Integer> l = Arrays.asList(a);
Ni siquiera se compilará
Type mismatch: cannot convert from List<int[]> to List<Integer>
Compruebe también ¿Por qué una matriz no es asignable a Iterable? antes de contestar
Además, si usa alguna biblioteca (por ejemplo, Guava), explique por qué es la mejor. (Porque es de Google no es una respuesta completa: P)
Por último, dado que parece haber una tarea al respecto, evite publicar un código de tarea.
Respuestas:
Aunque necesita usar una
Integer
matriz (no unaint
matriz) para que esto funcione.Para las primitivas, puedes usar guayaba:
Para Java8: (de la respuesta de Jin Kwon)
fuente
int
, noInteger
2)List
ya está,Iterable
así que la tercera línea no tiene sentido.solo mis 2 centavos:
fuente
Iterator<Character>
de aString
. Implementar el suyoIterator
parece ser la única forma de evitar iterar innecesariamente a través de todos los valores para convertir del tipo de objeto al tipo primitivo (a través de Guava's,Ints.asList()
por ejemplo), solo para poder obtener unoIterator
delList
que se creó.Con Java 8, puedes hacer esto.
fuente
Guava proporciona el adaptador que desea como Int.asList () . Hay un equivalente para cada tipo primitivo en la clase asociada, por ejemplo,
Booleans
paraboolean
, etc.Las sugerencias anteriores para usar
Arrays.asList
no funcionarán, incluso si se compilan porque obtienes una enIterator<int[]>
lugar de unaIterator<Integer>
. Lo que sucede es que, en lugar de crear una lista respaldada por su matriz, creó una lista de matrices de 1 elemento que contiene su matriz.fuente
Tuve el mismo problema y lo resolví así:
El iterador en sí es un vago,
UnmodifiableIterator
pero eso es exactamente lo que necesitaba.fuente
En Java 8 o posterior,
Iterable
se devuelve una interfaz funcionalIterator
. Entonces puedes hacer esto.fuente
En primer lugar, solo puedo estar de acuerdo en que
Arrays.asList(T...)
es claramente la mejor solución para los tipos de envoltorios o matrices con tipos de datos no primitivos. Este método llama a un constructor de unaAbstractList
implementación estática privada simple en laArrays
clase que básicamente guarda la referencia de matriz dada como campo y simula una lista anulando los métodos necesarios.Si puede elegir entre un tipo primitivo o un tipo Wrapper para su matriz, usaría el tipo Wrapper para tales situaciones, pero, por supuesto, no siempre es útil o obligatorio. Solo habría dos posibilidades que puede hacer:
1) Puede crear una clase con un método estático para cada matriz de tipo de datos primitiva (
boolean, byte, short, int, long, char, float, double
devolviendo unIterable<
WrapperType>
. Estos métodos usarían clases anónimas deIterator
(además deIterable
) que pueden contener la referencia del argumento del método que comprende (por ejemplo, unint[]
) como campo para implementar los métodos.-> Este enfoque es eficaz y le ahorra memoria (a excepción de la memoria de los métodos recién creados, aunque el uso
Arrays.asList()
tomaría la memoria de la misma manera)2) Dado que las matrices no tienen métodos (como para leer al lado vincularon) tampoco pueden proporcionar una
Iterator
instancia. Si realmente es demasiado vago para escribir nuevas clases, debe usar una instancia de una clase ya existente que se implementeIterable
porque no hay otra forma de instanciar la clase de implementación cuyo constructor permite una matriz de tipo primitiva (porqueIterable
o un subtipo.La ÚNICA forma de crear una implementación derivada de Colección existente
Iterable
es usar un bucle (excepto que usa clases anónimas como se describió anteriormente) o crea una instancia de una no permite matrices con elementos de tipo primitivo) pero, que yo sepa, la API de Java no presenta una clase como esa. La razón del bucle puede explicarse fácilmente: para cada Colección necesita Objetos y los tipos de datos primitivos no son objetos. Los objetos son mucho más grandes que los tipos primitivos, por lo que requieren datos adicionales que deben generarse para cada elemento de la matriz de tipos primitivos. Eso significa que si dos formas de tres (usando o usando una Colección existente) requieren un agregado de objetos, debe crear para cada valor primitivo de suIterable
Object[]
Arrays.asList(T...)
int[]
matriz, el objeto contenedor. La tercera forma usaría la matriz tal como está y la usaría en una clase anónima, ya que creo que es preferible debido al rendimiento rápido.También hay una tercera estrategia que usa un
Object
argumento como para el método donde desea usar la matriz oIterable
y requeriría verificaciones de tipo para determinar qué tipo tiene el argumento, sin embargo, no lo recomendaría en absoluto, ya que generalmente debe tener en cuenta que el Objeto no siempre tiene el tipo requerido y que necesita un código separado para ciertos casos.En conclusión, es culpa del problemático sistema de tipo genérico de Java que no permite usar tipos primitivos como tipo genérico, lo que ahorraría mucho código al usar simplemente
Arrays.asList(T...)
. Por lo tanto, necesita programar para cada tipo de matriz primitiva, necesita un método de este tipo (que básicamente no hace ninguna diferencia en la memoria utilizada por un programa C ++ que crearía para cada argumento de tipo utilizado un método separado.fuente
Puedes usar
IterableOf
desde Cactoos :Luego, puede convertirlo en una lista usando
ListOf
:O simplemente esto:
fuente
Si bien ya se ha publicado una respuesta similar, creo que la razón para usar el nuevo PrimitiveIterator.OfInt no estaba clara. Una buena solución es usar Java 8 PrimitiveIterator ya que está especializado para tipos int primitivos (y evita la penalización adicional de boxing / unboxing):
Ref: https://doc.bccnsoft.com/docs/jdk8u12-docs/api/java/util/PrimitiveIterator.OfInt.html
fuente
En java8 IntSteam stream puede ser encajonado a stream de Integers.
Creo que el rendimiento importa en función del tamaño de la matriz.
fuente