Arrays.asList () vs Collections.singletonList ()

138

Existe uma vantagem (ou muita diferença) em usar Arrays.asList (algo) sobre Collections.singletonList (algo) para criar uma lista contendo um item? O último também torna a lista retornada imutável.

Howard Grimberg
fonte
8
Você pode jogar goiabas ImmutableList.of()e Lists.newArrayList()na mistura também.
precisa saber é
Como um aparte disso, tive Collections.singletonList () causado problemas quando um método retorna uma Lista que é modificada posteriormente no downstream.
Howard Grimberg
1
Java 10 tem verdadeira lista imutável: stackoverflow.com/a/52536126/1216775
akhil_mittal

Respostas:

207

Collections.singletonList(something)é imutável, enquanto que Arrays.asList(something)é uma Listrepresentação de tamanho fixo de uma matriz na qual a lista e a matriz são unidas no heap.

Arrays.asList(something)permite alterações não estruturais feitas a ele, que são refletidas na lista e na matriz conjunta. Ele lança UnsupportedOperationExceptionpara adicionar e remover elementos, embora você possa definir um elemento para um índice específico.

Quaisquer alterações feitas na lista retornadas por Collections.singletonList(something)resultarão em UnsupportedOperationException.

Além disso, a capacidade da lista retornada por Collections.singletonList(something)sempre será 1, diferentemente de Arrays.asList(something)cuja capacidade será o tamanho da matriz apoiada.

Kumar Abhinav
fonte
63

Eu apenas acrescentaria que a lista singleton não é apoiada por uma matriz e apenas tem uma referência a esse item. Presumivelmente, seria necessário menos memória e pode ser significativo, dependendo do número de listas que você deseja criar.

Aprendiz
fonte
Algum link ou código para apoiar esse ponto de eficiência de memória? Eu tenho esse Arrays.asList (ONLY_ONE_OBJECT) escrito amplamente em uma base de código e gostaria de descobrir se a substituição por Collections.singletonList () leva à eficiência da memória?
Rahul Saini
13

O método Arrays.asListretorna uma lista de tamanho fixo apoiada pela matriz especificada. O método retorna uma instância da ArrayListqual é uma classe estática aninhada privada que se estende AbstractListe não java.util.ArrayList. Esta classe estática fornece implementação de poucos métodos, por exemplo, set, indexOf, forEach, replaceAlletc. etc., mas quando invocamos, addela não tem implementação própria, e AbstractListé invocado o método from que lança java.lang.UnsupportedOperationException.

O Collections.singletonListretorna uma lista imutável que contém apenas o objeto especificado e é serializável também.

Em uma nota lateral, para listas imutáveis geralmente usamos o Collections.unmodifiableListque retorna uma visão não modificável da lista especificada.

List<String> srcList = Arrays.asList("Apple", "Mango", "Banana");
var fruits = new ArrayList<>(srcList);
var unmodifiableList = Collections.unmodifiableList(fruits);     
fruits.set(0, "Apricot");
var modFruit = unmodifiableList.get(0);
System.out.println(modFruit); // prints Apricot

Uma coleção de visualizações não modificáveis ​​é uma coleção que não pode ser modificada e também é uma visualização em uma coleção de suporte. Observe que as alterações na coleção de backup ainda podem ser possíveis e, se ocorrerem, serão visíveis na visualização inalterável.

Podemos ter uma lista imutável verdadeira no Java 10 e posterior. Existem duas maneiras de obter uma lista verdadeiramente inalterável :

  1. var unmodifiableList = List.copyOf(srcList);
  2. var unmodifiableList = srcList.stream().collect(Collectors.toUnmodifiableList()); Se alguma dessas duas variáveis ​​for usada, o valor ainda será "Apple" e não "Apricot".

Conforme o documento do Java 10 :

Os métodos de fábrica estático List.ofe List.copyOffornecem uma maneira conveniente de criar listas não modificáveis. As instâncias de lista criadas por esses métodos têm as seguintes características:

  1. Eles não são modificáveis . Os elementos não podem ser adicionados, removidos ou substituídos. Chamar qualquer método mutador na lista sempre fará UnsupportedOperationExceptioncom que seja lançado. No entanto, se os elementos contidos forem mutáveis, isso poderá causar a alteração do conteúdo da Lista.
  2. Eles não permitem elementos nulos. Tentativas de criá-los com elementos nulos resultam em NullPointerException.
  3. Eles são serializáveis ​​se todos os elementos forem serializáveis.
  4. A ordem dos elementos na lista é igual à ordem dos argumentos fornecidos ou dos elementos na matriz fornecida.
  5. Eles são value-based. Os chamadores não devem fazer suposições sobre a identidade das instâncias retornadas. As fábricas são livres para criar novas instâncias ou reutilizar as existentes. Portanto, operações sensíveis à identidade nessas instâncias (igualdade de referência (==), código de hash de identidade e sincronização) não são confiáveis ​​e devem ser evitadas.
  6. Eles são serializados conforme especificado na página Formulário serializado .
akhil_mittal
fonte