Inventário desses poços da lista de classes de coleção Java ao longo dos anos

Algumas linguagens de programação de alto nível atuais fornecerão várias implementações out-of-the-box de estruturas de dados. Por exemplo, a estrutura de coleção da linguagem de programação Java fornece várias implementações. As classes de coleção incluem Map e Collection. List é uma das classes de coleção que usamos com frequência. Muitos códigos de negócios não podem prescindir dela. Hoje, vamos dar uma olhada em alguns dos poços de List.

O primeiro poço: a lista retornada pelo método Arrays.asList não oferece suporte para adicionar e excluir operações

Por exemplo, executamos o seguinte código:

Listar <String> strings = Arrays.asList ("m", "g"); 
strings.add ("h"); 复制 代码

Irá lançar a exceção java.lang.UnsupportedOperationException, qual é o seu sistema operacional interno neste momento? Por que o ArrayList retornado não pode adicionar elementos a ele? Ainda podemos adicionar elementos no futuro? , E então abra o Debug Dafa de forma decisiva:

Verificou-se que o ArrayList retornado não é o java.util.ArrayList comumente usado, mas a classe interna java.util.Arrays.ArrayList de Arrays. O código-fonte do método de entrada Arrays.asList é o seguinte:

public static <T> List <T> asList (T ... a) { 
    return new ArrayList <> (a); 
} 复制 代码

O método retorna a classe interna estática java.util.Arrays.ArrayList de Arrays. Embora esta classe e java.util.ArrayList também herdam da classe abstrata java.util.AbstractList, é descoberto através do código-fonte desta classe que não tem um pai abstrato O método add da classe AbstractList é lançar java.lang.UnsupportedOperationException por padrão.


A causa raiz desse problema é que o método add das strings retornadas por nossa chamada é herdado do método add da classe pai abstrata, e o método da classe pai abstrata lança java.lang.UnsupportedOperationException por padrão.

O segundo poço, a nova lista retornada pelo método Arrays.asList e a modificação do grupo de parâmetros original do método afetarão um ao outro

Além do poço acima, que não oferece suporte à adição ou exclusão de elementos, o método Arrays.asList tem outro poço:


A partir do código acima, podemos descobrir que a modificação da matriz original afetará a nova Lista que obtivemos por meio do método Arrays.asList e nos aprofundaremos no código-fonte de java.util.Arrays.ArrayList:

classe estática privada ArrayList <E> extends AbstractList <E> 
        implementa RandomAccess, java.io.Serializable 
    { 
        private static final long serialVersionUID = -2764017481108945198L; 
        final privado E [] a; 

        ArrayList (E [] array) { 
            a = Objects.requireNonNull (array); 
        } 

        ... 

     }   
复制 代码

Pode-se verificar que o array original é usado diretamente, portanto, devemos prestar atenção especial à Lista obtida usando o método Arrays.asList, pois o array é compartilhado, e alguns bugs inesperados podem ocorrer quando da modificação mútua. Uma das posturas padrão é renovar uma List como um parâmetro do método de construção ArrayList (por exemplo, List stringList = new ArrayList <> (Arrays.asList (arrays))) ou através de Lists.newArrayList na biblioteca Guava, A nova lista retornada e a matriz original são desacopladas e não se afetarão mais.

O terceiro poço, atravessando diretamente a coleção List para excluir elementos, relatará um erro

Ao percorrer diretamente os elementos da coleção, adicionar ou excluir elementos irá relatar um erro. Por exemplo, execute o seguinte código:

List <String> stringList = Lists.newArrayList ("m", "g", "h"); 
for (String s: stringList) { 
    if (Arrays.asList ("m", "h"). contains (s)) { 
        stringList.remove (s); 
    } 
} 复制 代码

O código acima pode ser compilado e passado normalmente, mas java.util.ConcurrentModificationException será lançado quando executado. Olhando para o código-fonte, você pode descobrir que o método delete element remove irá modificar a estrutura da coleção, ou seja, modCount (o número de modificações reais na coleção) será modificado. No processo de loop, o número real de modificações do modCount da coleção de List atual é comparado com o número de modificações do iterador expectModCount. ExpectedModCount é o modCount na inicialização. Se os dois não forem iguais, ConcurrentModificationException será relatado. Existem duas maneiras principais de resolver o problema: 1. Use o método iterador de ArrayList para percorrer e chame o método. 2. No JDK 1.8+, você pode usar o método removeIf para excluir.

Finalmente, tenho uma pergunta sincera: chame o método remove de ArrayList para passar o número do tipo básico de int e o número do tipo de empacotamento de Integer.O resultado da execução é o mesmo?

Finalmente

Obrigado a todos por verem aqui, o artigo tem deficiências, e vocês podem salientar; se vocês acham que está bem escrito, por favor, me avisem.

Acho que você gosta

Origin blog.51cto.com/11436461/2547410
Recomendado
Clasificación