una resueltos matriz matrices llenar letras imprimir filas ejercicios crear con como columnas java arrays collections guava apache-commons

resueltos - matriz java filas columnas



¿Cómo puedo generar una lista o matriz de enteros secuenciales en Java? (8)

¿Existe una manera breve y dulce de generar una List<Integer> , o tal vez un Integer[] o int[] , con valores secuenciales desde algún valor de start hasta un valor end ?

Es decir, algo más corto que, pero equivalente a 1 de los siguientes:

void List<Integer> makeSequence(int begin, int end) { List<Integer> ret = new ArrayList<>(end - begin + 1); for (int i=begin; i<=end; i++) { ret.add(i); } return ret; }

El uso de guayaba está bien.

Actualizar:

Análisis de rendimiento

Dado que esta pregunta ha recibido varias buenas respuestas, tanto con el uso de Java 8 nativa y bibliotecas de terceros, pensé que probar el rendimiento de todas las soluciones.

La primera prueba simplemente prueba la creación de una lista de 10 elementos [1..10] utilizando los siguientes métodos:

  • classicArrayList : el código dado arriba en mi pregunta (y esencialmente lo mismo que la respuesta de adarshr).
  • eclipseCollections : el código proporcionado a continuación en la respuesta de Donald usando Eclipse Collections 8.0.
  • guavaRange : el código dado en la respuesta de daveb a continuación. Técnicamente, esto no crea un List<Integer> sino un ContiguousSet<Integer> - pero dado que implementa Iterable<Integer> en orden, en general funciona para mis propósitos.
  • intStreamRange : el código proporcionado en la respuesta de Vladimir a continuación, que usa IntStream.rangeClosed() - que se introdujo en Java 8.
  • streamIterate : el código proporcionado en la respuesta de Catalin a continuación, que también utiliza la funcionalidad IntStream introducida en Java 8.

Aquí están los resultados en kilo-operaciones por segundo (los números más altos son mejores), para todo lo anterior con listas de tamaño 10:

... y nuevamente para listas de tamaño 10,000:

Ese último gráfico es correcto: ¡las soluciones que no sean Eclipse y Guava son demasiado lentas para obtener una sola barra de píxeles! Las soluciones rápidas son entre 10.000 y 20.000 veces más rápidas que el resto.

Lo que está sucediendo aquí, por supuesto, es que las soluciones de guayaba y eclipse en realidad no materializan ningún tipo de lista de 10.000 elementos; simplemente son envoltorios de tamaño fijo alrededor de los puntos de inicio y final. Cada elemento se crea según sea necesario durante la iteración. Dado que en realidad no iteramos en esta prueba, el costo se difiere. Todas las otras soluciones realmente materializan la lista completa en la memoria y pagan un alto precio en un punto de referencia de solo creación.

Hagamos algo un poco más realista y también iteremos sobre todos los enteros, resumiéndolos. Entonces, en el caso de la variante IntStream.rangeClosed , la referencia se ve así:

@Benchmark public int intStreamRange() { List<Integer> ret = IntStream.rangeClosed(begin, end).boxed().collect(Collectors.toList()); int total = 0; for (int i : ret) { total += i; } return total; }

Aquí, las imágenes cambian mucho, aunque las soluciones sin materialización siguen siendo las más rápidas. Aquí está la longitud = 10:

... y longitud = 10,000:

La larga iteración sobre muchos elementos empareja mucho las cosas, pero el eclipse y la guayaba son más del doble de rápido incluso en la prueba de los 10.000 elementos.

Entonces, si realmente quieres un List<Integer> , las colecciones de eclipse parecen ser la mejor opción, pero por supuesto si usas streams de una forma más nativa (por ejemplo, olvidando .boxed() y haciendo una reducción en el dominio primitivo) you '' Probablemente termine más rápido que todas estas variantes.

1 Quizás con la excepción del manejo de errores, por ejemplo, si end < begin , o si el tamaño excede algunos límites de implementación o JVM (p. Ej., Arreglos mayores a 2^31-1 .


Bueno, este trazador de líneas puede calificar (usa rangos de guayaba )

ContiguousSet<Integer> integerList = ContiguousSet.create(Range.closedOpen(0, 10), DiscreteDomain.integers()); System.out.println(integerList);

Esto no crea una List<Integer> , pero ContiguousSet ofrece la misma funcionalidad, en particular la implementación de Integer<Integer> que permite la implementación de foreach de la misma manera que List<Integer> .

En versiones anteriores (en algún lugar antes de Guava 14) puede usar esto:

ImmutableList<Integer> integerList = Ranges.closedOpen(0, 10).asSet(DiscreteDomains.integers()).asList(); System.out.println(integerList);

Ambos producen:

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


Con Java 8 es tan simple que ya no necesita ningún método aparte:

List<Integer> range = IntStream.rangeClosed(start, end) .boxed().collect(Collectors.toList());


Este podría funcionar para usted ....

void List<Integer> makeSequence(int begin, int end) { AtomicInteger ai=new AtomicInteger(begin); List<Integer> ret = new ArrayList(end-begin+1); while ( end-->begin) { ret.add(ai.getAndIncrement()); } return ret; }


Esto es lo más corto que pude encontrar.

Versión de lista

public List<Integer> makeSequence(int begin, int end) { List<Integer> ret = new ArrayList<Integer>(++end - begin); for (; begin < end; ) ret.add(begin++); return ret; }

Array Version

public int[] makeSequence(int begin, int end) { if(end < begin) return null; int[] ret = new int[++end - begin]; for (int i=0; begin < end; ) ret[i++] = begin++; return ret; }


Esto es lo más corto que puedo obtener usando Core Java.

List<Integer> makeSequence(int begin, int end) { List<Integer> ret = new ArrayList(end - begin + 1); for(int i = begin; i <= end; i++, ret.add(i)); return ret; }


La siguiente versión Java de una línea generará [1, 2, 3 ... 10]. El primer arg de iterate es el primer nr en la secuencia, y el primer arg de limit es el último número.

List<Integer> numbers = Stream.iterate(1, n -> n + 1) .limit(10) .collect(Collectors.toList());


Podría usar rangos de guayaba

Puedes obtener un SortedSet usando

ImmutableSortedSet<Integer> set = Ranges.open(1, 5).asSet(DiscreteDomains.integers()); // set contains [2, 3, 4]


Puede usar la clase Interval de Eclipse Collections .

List<Integer> range = Interval.oneTo(10); range.forEach(System.out::print); // prints 12345678910

La clase Interval es floja, por lo que no almacena todos los valores.

LazyIterable<Integer> range = Interval.oneTo(10); System.out.println(range.makeString(",")); // prints 1,2,3,4,5,6,7,8,9,10

Su método podría implementarse de la siguiente manera:

public List<Integer> makeSequence(int begin, int end) { return Interval.fromTo(begin, end); }

Si desea evitar el boxeo como enteros, pero le gustaría una estructura de lista como resultado, puede usar IntList con IntInterval desde Eclipse Collections.

public IntList makeSequence(int begin, int end) { return IntInterval.fromTo(begin, end); }

IntList tiene los métodos sum() , min() , minIfEmpty() , max() , maxIfEmpty() , average() y median() disponibles en la interfaz.

Actualización para mayor claridad: 27/11/2017

Un Interval es una List<Integer> , pero es flojo e inmutable. Es extremadamente útil para generar datos de prueba, especialmente si manejas mucho con colecciones. Si lo desea, puede copiar fácilmente un intervalo en una List , Set o Bag siguiente manera:

Interval integers = Interval.oneTo(10); Set<Integer> set = integers.toSet(); List<Integer> list = integers.toList(); Bag<Integer> bag = integers.toBag();

Un IntInterval es una IntList que extiende IntList . También tiene métodos de conversión.

IntInterval ints = IntInterval.oneTo(10); IntSet set = ints.toSet(); IntList list = ints.toList(); IntBag bag = ints.toBag();

Un Interval y un IntInterval no tienen el mismo contrato equals .

Actualización para Eclipse Collections 9.0

Ahora puede crear colecciones primitivas a partir de flujos primitivos. Existen con ofAll métodos y de ofAll dependiendo de su preferencia. Si tienes curiosidad, te explico por qué tenemos ambas here . Estos métodos existen para listas Int / Long / Double mutables e inmutables, Sets, Bags y Stacks.

Assert.assertEquals( IntInterval.oneTo(10), IntLists.mutable.withAll(IntStream.rangeClosed(1, 10))); Assert.assertEquals( IntInterval.oneTo(10), IntLists.immutable.withAll(IntStream.rangeClosed(1, 10)));

Nota: soy un committer para las colecciones de Eclipse