java中List删除时需要的注意事项

java中的LIST在删除时,一般会用list.remove(o); 但这样往往会出现问题,先来看下面的这段代码:

package com.demo;

import java.util.ArrayList;
import java.util.List;

public class Test11 {

  public void delete(){
    List<Integer> list = new ArrayList<Integer>();
    list.add(1);
    list.add(2);
    list.add(2);
    list.add(3);
    for (int i = 0; i < list.size(); i++) {
      if(list.get(i)==2){
        list.remove(i);
      }
    }
    this.outputList(list);
  }

  private void outputList(List<Integer> list){
    for (Integer i : list) {
      System.out.println(i);
    }
  }

  public static void main(String[] args) {
    Test11 t = new Test11();
    t.delete();

  }

}

返回结果是:

1

2

3

这结果显然不是我们的预期,我们是希望删除List中所有为2的元素,但输出结果中却出现了2,这是因为在i等于1时,删除了List中的index为1的元素2,这时候list为[1,2,3], 但接下来,i递增后,等于2,在list.get(i)时,取出来的结果就成为了3了,也就是说随着list元素的删除,index是随之变化的,这就是其中的陷阱,于是,我们得寻找一个在删除时,索引不发生变化的迭代方式来删除,而iterator是被创建之后会建立一个指向原来对象的单链索引表,当原来的对象数量发生变化时,这个索引表的内容不会同步改变,也就是用cursor来维护这个索引表,于是,可以这样来删除:

package com.demo;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Test11 {

  public void delete(){
    List<Integer> list = new ArrayList<Integer>();
    list.add(1);
    list.add(2);
    list.add(2);
    list.add(3);
    this.iteratorDelete(list.iterator(), 2);
    this.outputList(list);
  }

  private void iteratorDelete(Iterator<Integer> it, int deleteObject){
    while(it.hasNext()){
      int i = it.next();
      if(i==deleteObject){
        it.remove();
      }
    }
  }

  private void outputList(List<Integer> list){
    for (Integer i : list) {
      System.out.println(i);
    }
  }

  public static void main(String[] args) {
    Test11 t = new Test11();
    t.delete();

  }

}

这个代码结果就是正确的了!

可能有人会说,我是在iterator中删除的,为什么list的值会发生改变?这个问题,自已思考去吧!思考不出来,可以转行了!

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

(0)

相关推荐

  • java 中List删除实例详解

    java 中List删除实例详解 1.循环删除List中的元素 public static void main(String[] args) { List<String> t=new ArrayList<String>(); for (int i = 0; i < 10; i++) { t.add(""+i+""); } System.out.println("原有的List:"+t.toString()); for

  • java中List删除时需要的注意事项

    java中的LIST在删除时,一般会用list.remove(o); 但这样往往会出现问题,先来看下面的这段代码: package com.demo; import java.util.ArrayList; import java.util.List; public class Test11 { public void delete(){ List<Integer> list = new ArrayList<Integer>(); list.add(1); list.add(2);

  • java中循环删除list中元素的方法总结

    印象中循环删除list中的元素使用for循环的方式是有问题的,但是可以使用增强的for循环,然后今天在使用时发现报错了,然后去科普了一下,再然后发现这是一个误区.下面就来讲一讲..伸手党可直接跳至文末.看总结.. JAVA中循环遍历list有三种方式for循环.增强for循环(也就是常说的foreach循环).iterator遍历. 1.for循环遍历list for(int i=0;i<list.size();i++){ if(list.get(i).equals("del")

  • Java中 equals 重写时为什么一定也要重写 hashCode

    目录 1.equals 方法 2.hashCode 方法 2.1 hashCode 使用 3.为什么要一起重写? 3.1 Set 正常使用 3.2 Set 集合的“异常” 3.3 解决“异常” 3.4 原因分析 总结 前言: equals 方法和 hashCode 方法是 Object 类中的两个基础方法,它们共同协作来判断两个对象是否相等.为什么要这样设计嘞?原因就出在“性能” 2 字上. 使用过 HashMap 我们就知道,通过 hash 计算之后,我们就可以直接定位出某个值存储的位置了,那

  • 关于Java中增强for循环使用的注意事项

    序言 for循环语句是java循环语句中最常用的循环语句,一般用在循环次数已知的情况下使用.for循环语句的语法格式如下: java语言 for语句的用法   for(初始化表达式;循环条件;操作表达式){          执行语句          -- } 开发过程中,使用for循环遍历集合或数组是司空见惯的一件事,大家也习惯这样操作,但是有时候为了简便,我们可能会使用增强for循环,也就是类似for(String s : strList )写法,但是有时候稍有不慎,可能会带来一些莫名奇妙

  • Java中Process类的使用与注意事项说明

    目录 Process类的使用与注意事项说明 1.在项目开发中 2.在这里就需要认识一下process类 3.来说说今天业务需求[waitfor()]: 4.前不久遇到一个奇怪的问题就是ajax调用没有返回值 java的Process深入讲解 Process类的使用与注意事项说明 1.在项目开发中 经常会遇到调用其它程序功能的业务需求,在java中通常有两种实现方法 Runtime runtime = Runtime.getRuntime(); Process p = runtime.exec(c

  • 详解JAVA中的for-each循环与迭代

    在学习java中的collection时注意到,collection层次的根接口Collection实现了Iterable<T>接口(位于java.lang包中),实现这个接口允许对象成为 "foreach" 语句的目标,而此接口中的唯一方法,实现的就是返回一个在一组 T 类型的元素上进行迭代的迭代器. 一.迭代器Iterator 接口:Iterator<T> public interface Iterator<E>{ boolean hasNext

  • 简述Java中进程与线程的关系_动力节点Java学院整理

    概述 进程与线程,本质意义上说, 是操作系统的调度单位,可以看成是一种操作系统 "资源" .Java 作为与平台无关的编程语言,必然会对底层(操作系统)提供的功能进行进一步的封装,以平台无关的编程接口供程序员使用,进程与线程作为操作系统核心概念的一部分无疑亦是如此.在 Java 语言中,对进程和线程的封装,分别提供了 Process 和 Thread 相关的一些类.本文首先简单的介绍如何使用这些类来创建进程和线程,然后着重介绍这些类是如何和操作系统本地进程线程相对应的,给出了 Java

  • 浅谈Java中方法参数传递的问题

    可以理解当我们要调用一个方法时,我们会把指定的数值,传递给方法中的参数,这样方法中的参数就拥有了这个指定的值,可以使用该值,在方法中运算了.这种传递方式,我们称为参数传递.在这里,定义方法时,参数列表中的变量,我们称为形式参数. 调用方法时,传入给方法的数值,我们称为实际参数 在Java中调用方法时,如果参数是基本类型(byte/short/int/long/float/double/char/boolean)以及String类型时,形式参数的改变不影响实际参数. 以下代码在内存中发生的动作:

  • 为什么Java中只有值传递

    参数传递 在我们日常编写代码的过程中,调用函数可能是最常见的操作了.那么,在调用函数时,参数是怎么样传递的呢? 值传递 相信有很多人都是学C语言入门的,刚开始写代码时,用的最多的就是值传递了. void plus_one(int a){ a++; printf("a: %d", a); } int main(){ int n = 10; plus_one(n); printf("n:%d", n); return 0; } 这是一个简单的值传递的例子,无需多言,pl

随机推荐