Qual é a diferença entre
1.List<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia)); //copy
2.List<Integer> list2 = Arrays.asList(ia);
onde ia
é uma matriz de inteiros.
Fiquei sabendo que algumas operações não são permitidas list2
. por que é tão? como é armazenado na memória (referências / cópia)?
Quando eu embaralho as listas, list1
não afeta a matriz original, mas afeta list2
. Mas ainda list2
é um pouco confuso.
Como ArrayList
ser atualizado para a lista difere da criação de novosArrayList
list1 differs from (1)
ArrayList<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia));
java
list
collections
Dineshkumar
fonte
fonte
Lists.newArrayList(ia)
faz uma cópia independente, como a primeira opção. É simplesmente mais geral e melhor de se olhar.Respostas:
Primeiro, vamos ver o que isso faz:
Ele pega um array
ia
e cria um wrapper que o implementaList<Integer>
, o que torna o array original disponível como uma lista. Nada é copiado e tudo, apenas um único objeto wrapper é criado. As operações no wrapper da lista são propagadas para a matriz original. Isso significa que se você embaralhar o invólucro da lista, o array original também será; se você sobrescrever um elemento, ele será sobrescrito no array original, etc. Claro, algumasList
operações não são permitidas no invólucro, como adicionar ou removendo elementos da lista, você só pode ler ou sobrescrever os elementos.Observe que o wrapper de lista não se estende
ArrayList
- é um tipo diferente de objeto.ArrayList
s têm seu próprio array interno, no qual armazenam seus elementos e são capazes de redimensionar os arrays internos, etc. O wrapper não tem seu próprio array interno, ele apenas propaga operações para o array fornecido a ele.Por outro lado, se você subsequentemente criar uma nova matriz como
então você cria um novo
ArrayList
, que é uma cópia completa e independente do original. Embora aqui você também crie o wrapper usandoArrays.asList
, ele é usado apenas durante a construção do novoArrayList
e é coletado como lixo posteriormente. A estrutura deste novoArrayList
é completamente independente da matriz original. Ele contém os mesmos elementos (o array original e esta novaArrayList
referência os mesmos números inteiros na memória), mas cria um novo array interno que contém as referências. Então, quando você embaralha, adiciona, remove elementos, etc., o array original não é alterado.fonte
List<Integer>
para seus tipos de variáveis (ou argumentos de método, etc.). Isso torna seu código mais genérico e você pode alternar facilmente para outraList
implementação conforme necessário, sem ter que reescrever muito código.Bem, isso ocorre porque o
ArrayList
resultado deArrays.asList()
não é do tipojava.util.ArrayList
.Arrays.asList()
cria umArrayList
tipojava.util.Arrays$ArrayList
que não se estende,java.util.ArrayList
mas apenas se estendejava.util.AbstractList
fonte
Nesse caso,
list1
é do tipoArrayList
.Aqui, a lista é retornada como uma
List
visualização, o que significa que ela possui apenas os métodos anexados a essa interface. Daí porque alguns métodos não são permitidoslist2
.Aqui, você ESTÁ criando um novo
ArrayList
. Você está simplesmente passando um valor no construtor. Este não é um exemplo de elenco. No elenco, pode se parecer mais com isto:fonte
Estou muito atrasado aqui, de qualquer forma senti que uma explicação com referências de doc seria melhor para quem procura uma resposta.
ArrayList tem um monte de construtores sobrecarregados
public ArrayList () - // retorna arraylist com capacidade padrão 10
public ArrayList (coleção c)
public ArrayList (int initialCapacity)
Então, quando passamos o objeto retornado Arrays.asList, isto é, List (AbstractList) para o segundo construtor acima, ele criará um novo array dinâmico (o tamanho do array aumenta à medida que adicionamos mais elementos do que sua capacidade e também os novos elementos não afetarão o array original ) cópia superficial da matriz original ( cópia superficial significa que copia apenas sobre as referências e não cria um novo conjunto dos mesmos objetos da matriz original)
fonte
ou
A Instrução Acima adiciona o invólucro na matriz de entrada. Portanto, os métodos como adicionar e remover não serão aplicáveis no objeto de referência de lista 'namesList'.
Se você tentar adicionar um elemento na matriz / lista existente, obterá "Exceção no thread" main "java.lang.UnsupportedOperationException".
A operação acima é somente leitura ou visualização.
Não podemos realizar a operação de adicionar ou remover no objeto da lista. Mas
ou
Na declaração acima, você criou uma instância concreta de uma classe ArrayList e passou uma lista como parâmetro.
Nesse caso, o método add & remove funcionará corretamente, pois ambos os métodos são da classe ArrayList, portanto, não obteremos nenhuma UnSupportedOperationException.
As alterações feitas no objeto Arraylist (método adicionar ou remover um elemento em / de uma arraylist) não serão refletidas no objeto java.util.List original.
fonte
Em primeiro lugar, a classe Arrays é uma classe de utilitário que contém no. de métodos utilitários para operar em Arrays (graças à classe Arrays, caso contrário, teríamos que criar nossos próprios métodos para agir em objetos Array)
Método asList ():
asList
método é um dos métodos utilitários deArray
classe, é um método estático, por isso podemos chamar este método pelo seu nome de classe (comoArrays.asList(T...a)
)ArrayList
objeto, ele apenas retorna uma referência de lista para oArray
objeto existente (agora, após usar oasList
método, duas referências aoArray
objeto existente são criadas)List
objeto, podem NÃO funcionar neste objeto Array usandoList
referência como, por exemplo,Array
o tamanho de s é fixo em comprimento, portanto, você obviamente não pode adicionar ou remover elementos doArray
objeto usando estaList
referência (comolist.add(10)
oulist.remove(10);
caso contrário, lançará UnsupportedOperationException)Array
do objeto s (já que você está operando em um objeto Array existente usando a referência de lista)No primeiro caso, você está criando um novo
Arraylist
objeto (no segundo caso, apenas a referência ao objeto Array existente é criada, mas não um novoArrayList
objeto), então agora existem dois objetos diferentes, um éArray
objeto e o outro éArrayList
objeto e nenhuma conexão entre eles (então as mudanças em um objeto não será refletido / afetado em outro objeto (que é no caso 2Array
eArraylist
são dois objetos diferentes)caso 1:
caso 2:
fonte
Muitas pessoas já responderam aos detalhes mecânicos, mas é importante notar: Esta é uma escolha de design ruim, por Java.
O
asList
método Java está documentado como "Retorna uma lista de tamanho fixo ...". Se você pegar seu resultado e chamar (digamos) o.add
método, ele lança umUnsupportedOperationException
. Este é um comportamento não intuitivo! Se um método diz que retorna umList
, a expectativa padrão é que ele retorne um objeto que suporte os métodos de interfaceList
. Um desenvolvedor não deve ter que memorizar qual dos váriosutil.List
métodos cria programasList
que não suportam realmente todos osList
métodos.Se eles tivessem nomeado o método
asImmutableList
, faria sentido. Ou se eles apenas tivessem o método retornando um realList
(e copiasse a matriz de apoio), faria sentido. Eles decidiram favorecer o desempenho em tempo de execução e nomes curtos, às custas de violar o Princípio da Menor Surpresa e a prática OO bom de evitarUnsupportedOperationException
s.(Além disso, os designers podem ter feito um
interface ImmutableList
, para evitar uma infinidade deUnsupportedOperationException
s.)fonte
Observe que, em Java 8, 'ia' acima deve ser Integer [] e não int []. Arrays.asList () de uma matriz int retorna uma lista com um único elemento. Ao usar o trecho de código do OP, o compilador detectará o problema, mas alguns métodos (por exemplo, Collections.shuffle ()) falharão silenciosamente em fazer o que você espera.
fonte
fonte
Arrays.asList()
este método retorna sua própria implementação de List. Ele pega uma matriz como um argumento e cria métodos e atributos sobre ela, já que não está copiando nenhum dado de uma matriz, mas usando a matriz original, isso causa alteração na matriz original quando você modifica lista retornada pelo
Arrays.asList()
método.por outro lado.
ArrayList(Arrays.asList());
é um construtor deArrayList
classe que recebe uma lista como argumento e retorna umArrayList
que é independente da lista ie.Arrays.asList()
neste caso, passou como um argumento. é por isso que você vê esses resultados;fonte
Na linha 2,
Arrays.asList(ia)
retorna umaList
referência do objeto de classe interna definido emArrays
, que também é chamado,ArrayList
mas é privado e apenas estendeAbstractList
. Isso significa que o que retornouArrays.asList(ia)
é um objeto de classe diferente do que você obtevenew ArrayList<Integer>
.Você não pode usar algumas operações na linha 2 porque a classe privada interna
Arrays
não fornece esses métodos.Dê uma olhada neste link e veja o que você pode fazer com a classe interna privada: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/ Arrays.java # Arrays.ArrayList
A linha 1 cria um novo
ArrayList
objeto copiando elementos do que você obtém na linha 2. Portanto, você pode fazer o que quiser, poisjava.util.ArrayList
fornece todos esses métodos.fonte
Resumo da diferença -
quando a lista é criada sem usar o novo método do operador Arrays.asList (), ele retorna Wrapper, o que significa
1. você pode realizar a operação de adicionar / atualizar.
2. as alterações feitas no array original também serão refletidas em List e vice-versa.
fonte
Em resposta a alguns comentários com perguntas sobre o comportamento de Arrays.asList () desde Java 8:
fonte