Artigo original: Java Array Methods – How to Print an Array in Java

Um array é uma estrutura de dados utilizada para armazenar dados de um mesmo tipo. Arrays armazenam seus elementos na memória de modo contíguo.

Em Java, arrays são objetos. Todos os métodos da classe dos objetos podem ser invocados em um array. Podemos armazenar um número fixo de elementos em um array.

Vamos declarar um array de um tipo primitivo simples:

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

Agora, vamos tentar imprimi-lo com o método System.out.println():

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

Por que o Java não imprimiu nosso array? O que está acontecendo por baixo dos panos?

O método System.out.println() converte o objeto que passamos para uma string chamando o método String.valueOf(). Se olharmos para a implementação do método String.valueOf(), veremos isso:

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

Se o objeto passado é null ele retorna null. Senão, ele chama obj.toString(). No final, System.out.println() chama toString() para imprimir a saída.

Se a classe daquele objeto não sobrescreve a implementação de Object.toString(), ele chamará o método Object.toString().

Object.toString() retorna getClass().getName()+‘@’+Integer.toHexString(hashCode()). Em outras palavras, ele simplesmente retornará: "nome_da_classe@código_hash_do_objeto".

No nosso resultado anterior [I@74a14482 , o [ constata que isso é um array, e I significa int (número inteiro, o tipo do array). 74a14482 é a representação em hexadecimal sem sinal do código hash do array.

Sempre que criarmos nossas próprias classes, é uma boa prática sobrescrever o método Object.toString().

Não podemos imprimir arrays em Java simplesmente usando o método System.out.println(). Em vez disso, essas são algumas maneiras de imprimir um array:

  1. Laços: laço for e laço for-each
  2. Método Arrays.toString()
  3. Método Arrays.deepToString()
  4. Método Arrays.asList()
  5. Interface Iterator do Java
  6. API Stream do Java

Vamos vê-las uma por uma.

1. Laços: laço for e laço for-each

Aqui está um exemplo de um laço for:

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

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

Todas as classes wrapper sobrescrevem Object.toString() e retornam uma representação dos seus valores em string.

Aqui está um laço for-each:

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

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

2. Método Arrays.toString()

Arrays.toString() é um método estático da classe Arrays que pertence ao pacote java.util. Ele retorna uma representação em string do conteúdo do array especificado. Podemos imprimir arrays unidimensionais usando esse método.

Os elementos do array são convertidos para string usando o método String.valueOf(), desta forma:

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

Para um array de referências, temos que ter certeza de que a classe dessas referências sobrescreve o método Object.toString().

Por exemplo:

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

class Student {
    private String name;

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

    public String getName() {
        return name;
    }

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

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

Esse método não é apropriado para arrays multidimensionais. Ele converte arrays multidimensionais em strings usando o método Object.toString(), o que retorna suas identidades ao invés de seus conteúdos.

Por exemplo:

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

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

Com a ajuda do método Arrays.deepToString(), podemos imprimir arrays multidimensionais.

3. Método Arrays.deepToString()

Arrays.deepToString() retorna uma representação em string dos "conteúdos profundos" do array especificado.

Se um elemento é um array de tipo primitivo, ele é convertido para string através da invocação da sobrecarga apropriada de Arrays.toString().

Aqui está um exemplo de um array multidimensional de tipo primitivo:

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

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

Se um elemento é um array de referências, ele é convertido para string através de uma chamada recursiva do método Arrays.deepToString().

Teacher[][] teachers = 
{{ new Teacher("John"), new Teacher("David") }, {new Teacher("Mary")} };

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

Temos que sobrescrever o método Object.toString() na nossa classe Teacher.

Se você está curioso sobre como ele faz a recursão, aqui está o código-fonte para o método Arrays.deepToString().

Observação: arrays de referência unidimensionais também podem ser impressos usando esse método. Por exemplo:

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

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

4. Método Arrays.asList()

Esse método retorna uma lista de tamanho fixo criada a partir do array especificado.

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

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

Mudamos o tipo de int para Integer, porque List é uma coleção que armazena uma lista de objetos. Quando estamos convertendo um array em uma lista, o array deve ser de referências.

Java chama Arrays.asList(intArray).toString(). Internamente, essa técnica usa o método toString() do tipo dos elementos que estão na lista.

Temos outro exemplo abaixo, com a nossa classe customizada Teacher:

Teacher[] teacher = { new Teacher("John"), new Teacher("Mary") };

System.out.println(Arrays.asList(teacher));
// Resultado: [Teacher{name='John'}, Teacher{name='Mary'}]

OBSERVAÇÃO: não podemos imprimir arrays multidimensionais usando esse método. Por exemplo:

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

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

5. Interface Iterator

Do mesmo modo que com o laço for-each, podemos usar a interface Iterator para percorrer os elementos do array e imprimi-los.

Um objeto Iterator pode ser criado invocando o método iterator() em uma Collection. Esse objeto será usado para iterar sobre os elementos dessa Collection.

Aqui está um exemplo de como poderíamos imprimir um array usando a interface Iterator:

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

// Criando uma List de Integer
List<Integer> list = Arrays.asList(intArray);

// Criando um Iterator dessa lista de números inteiros
Iterator<Integer> it = list.iterator();

// Se a lista tiver elementos para serem iterados
while(it.hasNext()) {
    System.out.print(it.next());
    // Resultado: 25461234
}

6. API Stream do Java

A API Stream é usada para processar coleções de objetos. Uma stream é uma sequência de objetos. Streams não mudam a estrutura de dados original. Elas apenas fornecem o resultado de cada operação requisitada.

Com a ajuda da operação de terminal forEach(), podemos iterar sobre cada elemento da stream.

Por exemplo:

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

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

Agora, sabemos como imprimir um array em Java.

Obrigado pela leitura.

Imagem de Aziz Acharki, extraída do Unsplash.

Você pode ler outros artigos do autor (em inglês) no Medium e no freeCodeCamp.

Boa programação para você!