Escreva o título do diretório aqui
A Lista do Java geralmente usa métodos ao excluir elementos
list.remove(o)/remove(i)
. Ao usá-lo, é fácil cair na armadilha e obter resultados inesperados. Resuma experiências passadas e registre-as para compartilhar com todos.
inicializar matriz
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(3);
list.add(4);
list.add(5);
System.out.println("初始化数组:"+list);// 初始化数组:[1, 2, 3, 3, 4, 5]
}
Loop for comum
Atravessar lista para excluir elementos especificados ➡ Erro
public static void test(List<Integer> list){
for(int i=0;i<list.size();i++){
if(list.get(i)==3) {
list.remove(i);
}
}
System.out.println("for循环删除结果:"+list);// for循环删除结果:[1, 2, 3, 4, 5]
}
Após a chamada do método List remove(index)
, o elemento na posição do índice será removido e todos os elementos após o índice serão deslocados para a esquerda, ou seja, o índice será -1 em sequência. Para garantir que todos os dados possam ser operados , o índice-1 precisa ser definido, caso contrário, o índice original será index+ O elemento de 1 não pode ser percorrido (porque o índice original dos dados é index+1, após a operação de remoção ser executada, o índice se torna índice. Se houver não há operação do índice-1, o elemento não será percorrido, mas percorrido o próximo elemento deste elemento).
Portanto, é viável usar um loop for para excluir os elementos da Lista, ajustar o índice de forma síncrona após a exclusão dos elementos ou percorrer na ordem inversa para excluir os elementos .
Ajuste sincronizadamente o índice após excluir um elemento ➡ Correto
public static void test2(List<Integer> list){
for(int i=0;i<list.size();i++){
if(list.get(i)==3) {
list.remove(i--);
}
}
System.out.println("for循环删除结果后调整索引:"+list);// for循环删除结果后调整索引:[1, 2, 4, 5]
}
Percorra na ordem inversa para excluir elementos ➡ Correto
public static void test3(List<Integer> list){
for(int i=list.size()-1;i>=0;i--){
if(list.get(i)==3){
list.remove(i);
}
}
System.out.println("倒叙for循环删除结果"+list);// 倒叙for循环删除结果[1, 2, 4, 5]
}
travessia foreach
foreach percorre a lista para excluir elementos ➡ Erro
lançar uma exceção:
java.util.ConcurrentModificationException
O método de escrita foreach é na verdade a abreviatura do método Iterable
correto . Portanto, começamos com a análise do código-fonte e rastreamos o método, que retorna o objeto iterador Itr.hasNext
next
List.iterator()
iterator()
Através do código, descobrimos que Itr é uma classe interna privada definida em ArrayList. O método será chamado nos métodos next
e . A função deste método é determinar se eles são iguais. Se não forem iguais, uma exceção será jogado.remove
checkForComodification
modCount != expectedModCount
ConcurrentModificationException
Após cada execução normal remove
do método, a execução será atribuída expectedModCount = modCount
para garantir que os dois valores sejam iguais. Então o problema fica basicamente claro. Quando executado no loop foreach list.remove(item);
, o objeto da lista modCount 值
é modificado, mas o iterador de o objeto da lista expectedModCount 值
não é modificado, lançando assim ConcurrentModificationException
uma exceção.
Iterar
Excluir iterativamente os elementos da lista ➡ Correto
Todos os tipos de objetos de coleção em Java implementam a interface Iterator e podem ser iterados durante a travessia:
public static void test5(List<Integer> list){
Iterator<Integer> it=list.iterator();
while(it.hasNext()){
if(it.next()==3){
it.remove();
}
}
System.out.println("迭代删除List元素:"+list);// 迭代删除List元素:[1, 2, 4, 5]
}
Iterator.remove()
Este método excluirá o objeto de iteração atual, mantendo o índice do elemento original . Portanto, excluir elementos usando iteração é a maneira mais segura
Travessia iterativa, use o método list.remove(i) para excluir elementos ➡ Erro
public static void test6(List<Integer> list){
Iterator<Integer> it=list.iterator();
while(it.hasNext()){
Integer value=it.next();
if(value==3){
list.remove(value);
}
}
System.out.println("迭代遍历,用list.remove(i)方法删除元素:"+list);
}
Lança uma exceção:
java.util.ConcurrentModificationException
, o princípio é o mesmo do foreach para percorrer a Lista e deletar elementos
Método Collection.removeIf() exclui ➡ Correto
removeIf()
O método é usado para excluir todos os elementos do array que atendam a certas condições.
removeIf()
A sintaxe do método é:arraylist.removeIf(Predicate<E> filter)
Nota: arraylist é um objeto da classe ArrayList.
Descrição do parâmetro: filter - filtro para determinar se o elemento deve ser excluído
. Valor de retorno: Retorna verdadeiro se o elemento for excluído.
public static void test7(List<Integer> list){
list.removeIf(item->{
/*其他逻辑*/return item==3;});
System.out.println("Collection.removeIf()方法删除:"+list); // Collection.removeIf()方法删除:[1, 2, 4, 5]
}
No JDK1.8 e suas subclasses, foram adicionados Collection
novos métodos, que são usados para filtrar elementos na coleção de acordo com certas regras.removeIf()
Uso: método removeif() da coleção , uso de removeIf
outro
Ao excluir elementos da Lista, preste atenção à diferença entre o tipo Integer e o tipo int.
Exclua o elemento 2 diretamente, o código é o seguinte:
list.remove(2);
System.out.println(list); //
Pode-se observar que quando um número é passado ao excluir um elemento da Lista, ele será excluído por índice por padrão. Se você precisar excluir o objeto Integer, chame remove(object)
o método e passe-o Integer类型
. O código é o seguinte:
list.remove(new Integer(2));
System.out.println(list); // [1, 3, 3, 4]
Resumir
- Ao usar um loop for para percorrer uma lista para excluir elementos, você precisa prestar atenção ao problema de que os elementos serão deslocados para a esquerda.
- Ao excluir elementos da Lista, para evitar armadilhas, é recomendado usar um iterador
remove()
ouremoveIf()
- Ao excluir elementos da Lista, eles são excluídos por índice por padrão, em vez da exclusão do objeto.