Temas avanzados de arreglos en Java


Los arreglos son estructuras de datos estáticas ordenadas en memoria que almacenan datos del mismo tipo, estos pueden ser de tipo primitivo u objetos, en este post daremos una explicación a detalle sobre los tipos de arreglos y como utilizarlos correctamente en Java.

Existen 3 formas de crear arreglos en Java a continuación se explica cada una de ellas.

Creación de arreglos explícita

Para crear un arreglo de forma explícita se creará siguiendo la siguiente sintaxis:

 int array[]=new int[20]

Entendamos cada una de las partes de la línea anterior:

  • int array[]   : Es la definición de la referencia la cual dice que se creará un arreglo de tipo entero uni dimensional.
  • new int[20] : Como todo a excepción de los tipos de datos primitivos en Java, los arreglos son objetos, por esto es necesario utilizar el operador new para crearlos, el número 20 define que el arreglo tendrá una capacidad de 20 elementos de tipo entero.

La creación de arreglos de forma explícita se utiliza cuando sabemos tanto la cantidad de elementos a utilizar como su tipo, pero no conocemos aún lo que se almacenará dentro del mismo.

Creación de arreglos de forma implícita

Para crear un arreglo de forma implícita se seguirá la siguiente sintaxis:

int arr[]={1,2,3,4,5,6};

Entendamos cada una de las partes de la línea anterior:

  • int arr[]: Del mismo modo que en el ejemplo anterior, define una referencia unidimensional a un arreglo de enteros.
  • {1,2,3,4,5,6}: Como se puede observar no es necesario utilizar el operador new, ni el tamaño ya que se está creando de forma implícita, solo es necesario definir los elementos que contendrá y el objeto será creado por java. Es importante mencionar que aunque no se utilice el operador new el arreglo seguirá siendo un objeto y aunque no se defina un tamaño este será asignado de acuerdo al número de elementos que se definan y no podrá ser modificado.

La creación de arreglos de forma implícita es utilizada cuando desde el momento en el que se crea el arreglo se conocen los valores que contendrá, esto ayuda a hacer el código más legible y que no se tenga que asignar posición por posición el contenido.

Creación de arreglos de forma anónima

Esta es una de las formas menos conocidas para crear arreglos pero una de las más útiles, veamos la sintaxis necesaria para utilizarla:

int arr[] = new int[] { 1, 2, 3, 4, 5, 6, 6 };

Aunque la sintaxis es muy similar a la anterior, su uso es muy diferente, veamos la explicación de la línea anterior:

  • int arr[]: De igual modo a las anteriores define la referencia a la que se asignará este arreglo, en este caso será un arreglo unidimensional de enteros.
  • new int[]{1,2,3,4,5,6} : Del mismo modo a la anterior es posible definir desde su creación los elementos contenidos por el arreglo.

Tanto la creación de arreglos de forma implícita y anónima se ven muy similares y es un poco complejo entender en un principio cuando utilizar uno y cuando utilizar el otro, para esto veamos el siguiente ejemplo:

public void print(int[] arr) {
	for (int i : arr) {
		System.out.println(i);
	}
}

El método anterior es un método común que imprimirá los elementos que se encuentran en un arreglo. Ahora veamos como invocarlo utilizando un arreglo anónimo:

public void foo() {
	print(new int[] { 1, 2, 3, 4, 5, 6, 7 });
	// Many lines of code
}

El método foo tiene en su primera línea una llamada al método print(), como se puede ver le pusimos como parámetro un arreglo creado de forma anónima, de esto modo este objeto solo vivirá dentro de la ejecución del método print y una vez que este termine el arreglo será elegible para su destrucción por el Garbage collector, con esto es posible que tengamos muchas líneas de código después sin importarnos el arreglo ya que este será destruido .

Ahora es turno de que veamos el mismo código pero haciendo uso de un arreglo creado de forma implícita:

public void foo() {
	int arr[]={ 1, 2, 3, 4, 5, 6, 7 };
	print(arr);
	// Many lines of code
}

Aunque el código se ve muy parecido existe una diferencia importante, como se puede ver se cuenta con una referencia llamada arr[] que apunta al arreglo que definimos dentro del método foo(), esto significa que una vez que se termine de ejecutar el método print() el arreglo no será elegible por el garbage collector hasta que termine la ejecución del método foo() y si este contiene mucho código o un proceso muy largo tendremos en memoria ese arreglo durante todo el proceso. Aunque es posible apuntar la referencia a null después del método print eso haría el código menos legible.

Veamos el siguiente código:

public void foo() {
	print({ 1, 2, 3, 4, 5, 6, 7 });
	// Many lines of code
}

Este es un error muy común, ya que es natural pensar pasarle la literal del arreglo directo al método sin asignarla a una referencia y de este modo podríamos utilizar el arreglo creado de forma implícita para resolver un problema, pero el código anterior resulta en un error de compilación.

Este ejemplo muestra de forma clara los beneficios de utilizar un arreglo anónimo y su uso en un programa real.

Arreglos unidimensionales vs arreglos de arreglos

Otra forma de clasificar los arreglos es por las dimensiones de los mismos, en Java esto es un poco diferente a otros lenguajes de programación ya que los arreglos multidimensionales en Java son considerados arreglos de arreglos, veamos la explicación:

Arreglos unidimensionales

Los ejemplos anteriores son ejemplos de arreglos uni dimensionales y estos son cuando tenemos solo un conjunto de números.

Arreglos de arreglos

Es en este punto el que me gustaría detallar más ya que es el que tiene un grado de complejidad mayor. Un arreglo de arreglos en Java es utilizado para manejar matrices de datos. La diferencia con otros lenguajes es que en lugar de que se cree el arreglo multidimensional se creará un arreglo base que tiene como valor objetos de tipo arreglo, veamos un ejemplo:

int arr[][]=new int[10][10];

La línea anterior define que se creará un arreglo que puede contener dentro 10 arreglos y cada uno de ellos puede almacenar 10 valores.

Arreglos irregulares

En el ejemplo anterior podríamos llegar a pensar que los arreglos de arreglos lucen exactamente igual a un arreglo multidimensional común y corriente definido en otros lenguajes, para entender como funcionan realmente explicaremos los arreglos irregulares. En el ejemplo anterior creamos un arreglo de 10 x 10 que se podría ver del siguiente modo:

0000000000
0000000000
0000000000
0000000000
0000000000
0000000000
0000000000
0000000000
0000000000
0000000000

Pero java da la flexibilidad de crear arreglos que no tengan esa estructura normal siempre, para esto introduce los arreglos irregulares, veamos un ejemplo:

int arr[][]=new int[3][];

Esta línea se puede ver muy parecida a la que definimos cuando hablamos de los arreglos multidimensionales, pero tiene una pequeña diferencia, en los segundos corchetes no estamos indicando un tamaño, lo cual significa que quiero un arreglo de 3 elementos y en cada uno de estos almacenaré otro arreglo unidimensional, veamos el código completo para definirlo:

int arr[][]=new int[3][];
arr[0]=new int[]{1,2,3,4,5};
arr[1]=new int[]{1,2};
arr[2]=new int[]{3,3,3,3,3,3,3,3,3};

Entendamos el código anterior:

  • Definimos un arreglo que puede almacenar 3 arreglos dentro de el
  • El primer arreglo almacenará 5 valores
  • El segundo arreglo almacenará 2 valores
  • El tercer arreglo almacenará 9 valores

El resultado de esto es un arreglo irregular, la siguiente es la salida si lo imprimimos del mismo modo que el anterior:

12345
12
333333333

Con esto queda claro que los arreglos en Java pueden no ser cuadrados con una dimensión como 5×5 si no que pueden contener formas mucho más complejas.

Puntos interesantes sobre los arreglos en Java

Veamos algunos puntos interesantes sobre arreglos de los que no hemos hablado:

  • Las siguientes son formas válidas para crear un arreglo:
    • int a[];
    • int []b;
    • int []c[];
  • Es posible hacer arreglos tanto de tipos de datos primitivos como de objetos.
  • Los arreglos son Objetos

Pregunta para el lector

Si eres de las personas a las que les gusta investigar, te dejamos el siguiente reto:

System.out.println(new int[]{1,2,3,4,5}.getClass());
System.out.println(new int[][]{{1,2},{2,3}}.getClass());
System.out.println(new int[][][]{{{7,7},{8,8},{3,3}},{{2,3},{1,2}}}.getClass());

Antes de ejecutar este código trata de adivinar la salida, una vez que lo hagas ejecútalo y sorpréndete con el resultado, investiga la razón y compártela con nosotros.

Si te gusta el contenido del blog compártelo con tus amigos y síguenos en nuestras redes sociales para estar al tanto de las publicaciones que realizamos.

Autor: Alejandro Agapito Bautista

Twitter: @raidentrance

Contacto:raidentrance@gmail.com

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s