Original article: Java Array Methods – How to Print an Array in Java

Un arreglo es una estructura de datos utilizada para almacenar datos del mismo tipo. Los arreglos almacenan sus elementos en ubicaciones de memoria contiguas.

En Java, los arreglos son objetos. Todos los métodos se pueden ser invocados en un arreglo. Podemos almacenar un número fijo de elementos en un arreglo.

Declaremos un tipo simple de arreglo primitivo:

int[] intArray = {2,5,46,12,34};

Ahora tratemos de imprimirlo con el método  System.out.println():

System.out.println(intArray);
// output: [I@74a14482

¿Por qué no imprimió Java nuestro arreglo? ¿Qué está pasando detrás de escena?

El método System.out.println()  convierte el objeto que pasamos en una cadena llamando  String.valueOf(). Sí miramos a la implementación del método String.valueOf(), veremos esto:

public static String valueOf(Object obj) {
    return (obj == null) ? "null" : obj.toString();
}

Si el objeto pasado es null retorna null, si no este llama obj.toString(). Finalmente, System.out.println() llama toString() a imprimir el resultado.

Si la clase de ese objeto anula la implementación de  Object.toString()'s, llamará al método Object.toString().

Object.toString() retorna getClass().getName()+‘@’+Integer.toHexString(hashCode()) . De modo simple, retorna: “nombre de la clase @ código hash del objeto”.

En nuestro resultado anterior [I@74a14482, el [ indica que se trata de un arreglo, y I representa int (el tipo de arreglo). 74a14482 es la representación  hexadecimal sin firma del código hash del arreglo.

Cada vez que estemos creando nuestras propias clases personalizadas, es una buena práctica anular el método Object.toString().

No podemos imprimir arreglos en Java usando el método System.out.println(). En vez de eso, estas son las formas en las que podemos imprimir un arreglo:

  1. Bucles: bucle for y bucle for-each
  2. método Arrays.toString()
  3. método Arrays.deepToString()
  4. método Arrays.asList()
  5. Interfaz Java Iterator
  6. Java Stream API

Veámoslos uno por uno.

1. Bucles: bucle for y bucle for-each

Aquí tenemos un ejemplo de un bucle for:

int[] intArray = {2,5,46,12,34};

for(int i=0; i<intArray.length; i++){
    System.out.print(intArray[i]);
    // output: 25461234
}

Todas las clases anulan  Object.toString() y regresan una representación de cadena de su valor.

Aquí tenemos un bucle for-each:

int[] intArray = {2,5,46,12,34};

for(int i: intArray){
    System.out.print(i);
    // output: 25461234
}

2. Método Arrays.toString()

Arrays.toString() es un método estático de la clase del arreglo que pertenece al paquete java.util. Retorna una representación de los contenidos del arreglo especificado. Podemos imprimir un arreglo unidimensional usando este método.

Los elementos del arreglo son convertidos a cadenas usando el método, String.valueOf(), de esta forma:

int[] intArray = {2,5,46,12,34};
System.out.println(Arrays.toString(intArray));
// output: [2, 5, 46, 12, 34]

Para un tipo de referencia del arreglo, tenemos que asegurarnos que la clase del tipo de referencia anula el método Object.toString().

Por ejemplo:

public class Test {
    public static void main(String[] args) {
        Estudiante[] estudiante = {new Estudiante("John"), new Estudiante("Doe")};
        
        System.out.println(Arrays.toString(estudiantes));
        // output: [Estudiante{name='John'}, Estudiante{name='Doe'}]
    }
}

class Estudiante {
    private String name;

    public Estudiante(String name){
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Estudiante{" + "name='" + name + '\'' + '}';
    }
}

Este método no es apropiado para arreglos multidimensionales. Convierte los arreglos multidimensionales a cadenas usando Object.toString() que describe sus identidades en vez de sus contenidos.

Por ejemplo:

// creating multidimensional array
int[][] multiDimensionalArr = { {2,3}, {5,9} };

System.out.println(Arrays.toString(multiDimensionalArr));
// output: [[I@74a14482, [I@1540e19d]

Con la ayuda de Arrays.deepToString(), podemos imprimir arreglos multidimensionales.

3. Método Arrays.deepToString()

Arrays.deepToString() retorna una representación de los "contenidos profundos" del arreglo especificado.

Si un elemento es un arreglo de un tipo primitivo, es convertido a una cadena invocando la sobrecarga adecuada de Arrays.toString().

Aquí tenemos un ejemplo del tipo primitivo de un arreglo multidimensional:

// creating multidimensional array
int[][] multiDimensionalArr = { {2,3}, {5,9} };

System.out.println(Arrays.deepToString(multiDimensionalArr));
// output: [[2, 3], [5, 9]]

Si un elemento es un arreglo del tipo de referencia, se convierte en una cadena invocando recursivamente Arrays.deepToString().

Profesor[][] profesores = 
{{ new Profesor("John"), new Profesor("David") }, {new Profesor("Mary")} };

System.out.println(Arrays.deepToString(teachers));
// output: 
[[Profesor{name='John'}, Profesor{name='David'}],[Profesor{name='Mary'}]]

Tenemos que anular  Object.toString() en nuestra clase Profesor.

Si tienes curiosidad de cómo lo hace recursión, aquí encuentras el código fuente para el método  Arrays.deepToString().

NOTA: Los arreglos unidimensionales de tipo de referencia también pueden ser impresos usando este método. Por ejemplo::

Integer[] oneDimensionalArr = {1,4,7};

System.out.println(Arrays.deepToString(oneDimensionalArr));
// output: [1, 4, 7]

4. Método Arrays.asList()

Este método regresa una lista de tamaño fijo respaldada por el arreglo especificado.

Integer[] intArray = {2,5,46,12,34};

System.out.println(Arrays.asList(intArray));
// output: [2, 5, 46, 12, 34]

Hemos cambiado el tipo int a un número entero, porque List es una colección que guarda una lista de objetos. Cuando estamos convirtiendo un arreglo a una lista debería ser un arreglo de tipo de referencia.

Java llama  Arrays.asList(intArray).toString(). Esta técnica usa internamente el método toString()  del tipo de los elementos dentro de la lista.

Otro ejemplo con nuestra clase personalizada Profesor:

Profesor[] profesor = { new Profesor("John"), new Profesor("Mary") };

System.out.println(Arrays.asList(profesor));
// output: [Profesor{name='John'}, Profesor{name='Mary'}]

NOTA: No podemos imprimir arreglos multidimensionales usando este método. Por ejemplo:

Teacher[][] teachers = 
{{ new Teacher("John"), new Teacher("David") }, { new Teacher("Mary") }};
        
System.out.println(Arrays.asList(teachers));

// output: [[Lcom.thano.article.printarray.Teacher;@1540e19d, [Lcom.thano.article.printarray.Teacher;@677327b6]

5. Interfaz del iterator Java

Similar a un bucle for-each, podemos usar la interfaz del iterador para recorrer los elementos del arreglo e imprimirlos.

Se puede crear un objeto iterator invocando el método iterator() sobre una colección (Collection). Ese objeto será usado para iterar sobre la Colección de elementos

Aquí tenemos un ejemplo de cómo podemos imprimir un arreglo usando la interfaz:

Integer[] intArray = {2,5,46,12,34};

// creando una lista de entero (List of Integer)
List<Integer> list = Arrays.asList(intArray);

// creando un  iterador de la lista de entero (Integer List)
Iterator<Integer> it = list.iterator();

// Si la lista tiene elementos que ser iterados
while(it.hasNext()) {
    System.out.print(it.next());
    // output: 25461234
}

6. Java Stream API

La Stream API es usa para procesar colecciones de objetos. Una corriente (stream) es una secuencia de objetos.  Las corrientes no cambian la estructura de datos original, solo proveen el resultado según las operaciones solicitadas.

Con la ayuda de a operación en el terminal forEach() podemos iterar a través de cada elemento de la corriente

Por ejemplo:

Integer[] intArray = {2,5,46,12,34};

Arrays.stream(intArray).forEach(System.out::print);
// output: 25461234

Ahora ya sabemos cómo imprimir un arreglo en Java.

Gracias por leerme.

Imagen de portada por Aziz Acharki en Unsplash.

Puedes leer mis otros artículos en Medium.

Happy Coding!