Inicialização da lista Java em uma linha

Inicialização da lista Java em uma linha

1. Introdução

Neste tutorial rápido, vamos investigar como podemos inicializar umList usando one-liners.

Leitura adicional:

Collections.emptyList() vs. Nova Instância da Lista

Aprenda as diferenças entre o Collections.emptyList () e uma nova instância da lista.

Read more

Guia para o Java ArrayList

Guia rápido e prático para o ArrayList em Java

Read more

2. Criar a partir de uma matriz

Podemos criar umList a partir de uma matriz e, graças aos literais de matriz, podemos inicializá-los em uma linha:

List list = Arrays.asList(new String[]{"foo", "bar"});

Podemos confiar no mecanismo varargs para lidar com a criação da matriz. Com isso, podemos escrever um código mais conciso e legível:

@Test
public void givenArraysAsList_thenInitialiseList() {
    List list = Arrays.asList("foo", "bar");

    assertTrue(list.contains("foo"));
}

The result instance of this code implements the List interface but it isn’t a java.util.ArrayList nor a LinkedList. Em vez disso, é umList apoiado pela matriz original, que tem duas implicações.

Embora o nome da classe sejaArrayList, mas está no pacotejava.util.Arrays.

2.1. Tamanho fixo

A instância de resultado deArrays.asList terá um tamanho fixo:

@Test(expected = UnsupportedOperationException.class)
public void givenArraysAsList_whenAdd_thenUnsupportedException() {
    List list = Arrays.asList("foo", "bar");

    list.add("baz");
}

2.2. Referência compartilhada

A matriz original e a lista compartilham as mesmas referências aos objetos:

@Test
public void givenArraysAsList_whenCreated_thenShareReference(){
    String[] array = {"foo", "bar"};
    List list = Arrays.asList(array);
    array[0] = "baz";

    assertEquals("baz", list.get(0));
}

3. Criar a partir de um fluxo (Java 8)

Podemos facilmente converter umStream em qualquer tipo deCollection.

Portanto, com os métodos de fábrica paraStreams, podemos criar e inicializar listas em uma linha:

@Test
public void givenStream_thenInitializeList(){
    List list = Stream.of("foo", "bar")
      .collect(Collectors.toList());

    assertTrue(list.contains("foo"));
}

Devemos marcar aqui queCollectors.toList() não garante a implementação exata doList retornado.

There’s no general contract about the mutability, serializability or thread-safety of the returned instance. Portanto, nosso código não deve depender de nenhuma dessas propriedades.

Algumas fontes destacam queStream.of(…).collect(…) pode ter maior memória e pegada de desempenho do queArrays.asList(), mas em quase todos os casos, é uma micro-otimização que há pouca diferença.

4. Métodos de fábrica (Java 9)

No JDK 9, vários métodos convenientes de fábrica foram introduzidos para coleções:

List list = List.of("foo", "bar", "baz");
Set set = Set.of("foo", "bar", "baz");

One important detail is the returned instances are immutable. Além disso, os métodos de fábrica têm várias vantagens em eficiência de espaço e segurança de linhas.

Este tópico é mais explorado emthis article.

5. Inicialização de chaves duplas

Em vários lugares, podemos encontrar um método chamado‘double brace initialization' que se parece com:

@Test
public void givenAnonymousInnerClass_thenInitialiseList() {
    List cities = new ArrayList() {{
        add("New York");
        add("Rio");
        add("Tokyo");
    }};

    assertTrue(cities.contains("New York"));
}

O nome‘double brace initialization' é bastante enganador. A sintaxe pode parecer compacta e elegante, mas esconde perigosamente o que está acontecendo sob o capô.

Na verdade, não há um elemento de sintaxe‘double brace' em Java, esses são dois blocos formatados intencionalmente desta forma.

With the outer braces, we declare an anonymous inner class which will be a subclass of the ArrayList. Dentro dessas chaves, podemos declarar os detalhes de nossa subclasse.

Como sempre, podemos usar blocos inicializadores de instância e é daí que o par interno de chaves vem.

A brevidade desta sintaxe é tentadora, mas é considerada um antipadrão.

Para ler mais sobre a inicialização de chave dupla, dê uma olhada em nosso artigohere.

6. Conclusão

Modern Java offers several options to create a Collection in one line. O método que escolhemos se deve quase inteiramente à preferência pessoal, ao invés de raciocínio técnico.

Uma lição importante é que, embora pareça elegante,the anti-pattern of anonymous inner class initialization (a.k.a. ‘double brace') has many negative side-effects.

Como sempre, o código está disponívelover on GitHub.