ArrayList集合中remove()方法分析(根据什么remove()删除)

观察下面两段代码

ArrayList<Integer>list=new ArrayList<>();         
		list.add(1);
		list.add(1);
		System.out.println(list.size());             //输出2
		
		list.remove(new Integer(1));        //基本类型的包装类
		System.out.println(list.size());             //输出1	
		
		list.add(new Integer(1));
		System.out.println(list.size());             //输出2
		
		list.remove(1);
		System.out.println(list.size());             //输出1	
	ArrayList<String>list=new ArrayList<>();
		list.add("Tom");
		list.add("Tom");
		System.out.println(list.size());	//输出2
		
		list.remove(new String("Tom"));
		System.out.println(list.size());    //输出1
		list.remove(new String("Tom"));
		System.out.println(list.size());    //输出0
		
		
		list.add(new String("Tom"));
		System.out.println(list.size());    //输出1
		
		list.remove("Tom");
		System.out.println(list.size());    //输出0

不难看出
List接口的实现类ArrayList类中,使用add()方法,可以添加相同的元素(/此处不做过多分析,主要分析remove)
1.当类型为String类型时中remove的执行
方法如下,是否删除成功返回布尔类型。根据什么删除,读取下方代码。
remove(new String(“Tom”) //String类型的对象传入reomve()中的参数Objec o中,o不为null,执行else,if中的判断条件o.equals(elementData[index]) 此时的o是remove中的Tom,遍历执行if条件中equals()方法,与数组中已经存储的元素进行比对,内容相同,则根据索引删除,retrun ture删除成功,结束方法 若未找到内容相同的数组内元素,则会执行下方return false
!!!所以,当类型为String类型时,equals比较内容是否相同进行remove删除操作,过程发生遍历,遍历集合中的元素,与参数中String类的声明方式无关;又因为是return ture,所以只会删除一次内容相同的元素,尽管ArrayList集合中可以存储相同元素。

 public boolean remove(Object o) {
        if (o == null) {
            for (int index = 0; index < size; index++)
                if (elementData[index] == null) {
                    fastRemove(index);
                    return true;
                }
        } else {
            for (int index = 0; index < size; index++)
                if (o.equals(elementData[index])) {
                    fastRemove(index);
                    return true;
                }
        }
        return false;
    }

2.数据为基本数据类型数据 或是 基本类型数据的包装类中remove的执行
仍然会执行上述代码中的remove方法,此时list.remove(new Integer(1));
就相当于Object o=new Integer(1);o.equals(elementData[index])
Integer类中的equals()方法如下

 public boolean equals(Object obj) {
        if (obj instanceof Integer) {  //如果对象是Integer类型(final修饰的类,没有其他情况可考虑)】
            return value == ((Integer)obj).intValue();   //强制类型转换返回int值
        }
        return false;
    }

!!!所以,当类型为数据为基本数据类型数据 或是 基本类型数据的包装类时,remove根据比对 数值是否相等,来进行删除操作

3.类型为自定义类型时,代码如下,在同一个包下声明两个类

package com.ame;
import java.util.ArrayList;
public class RemoveOpe {
	public static void main(String[] args) {
		ArrayList<Person>list=new ArrayList<>();
		list.add(new Person("1"));
		list.add(new Person("2"));
	//	list.remove(new String("2"));
	//	System.out.println(list.size());
		list.remove(new Person("2"));
		System.out.println(list.size());
	}
}

class Person{
	private String id;
	public Person(String id) {
		this.id=id;
	}
	@Override
	public boolean equals(Object obj) {
		System.out.println(this);          //在Person中重写equals方法,添加打印语句帮助判断
		return super.equals(obj);
	}	
}

将上方代码上方代码注掉时,即只执行时

list.remove(new Person("2"));
System.out.println(list.size());

输出

com.ame.Person@52e922
com.ame.Person@52e922
2

没有删除成功 通过Person()中重写的equals方法可知o.equals(elementData[index])此时的o=com.ame.Person@52e922,是一个地址,输出两次,是因为list集合add了两个元素,此时index=2,for (int index = 0; index < size; index++) 遍历了两,执行了两次equals方法(o.equals(elementData[index]))与数组中元素进行比对,比对的是地址(如果不在自定义类中重写equals方法,则会执行Object中的equals方法,代码如下)
public boolean equals(Object obj) { return (this == obj); }

而只执行下方代码时

list.remove(new String("2"));
System.out.println(list.size());

输出

2

可见如果用String类型 声明相同内容,试图来remov自定义类型,删除失败,(此处没有打印地址是因为对象new String(“2”)执行的是String类中的equals方法,比较内容,前文已知自定义类型时数组元素elementData[index]中存储的是地址
类似com.ame.Person@52e922格式,数组elementData[]在ArrayList的对象list调用add方法时已经生成,数组元素的地址内容和String对象声明的’2’显然是不同的)

补充说明

Person p=new Person();
list.add(p);
System.out.println(list.size());
list.remove(p);
System.out.println(list.size());

类型是自定义类型时,必须是同一个对象,才能删除成功。可以通过自定义类型声明变量调用构造方法,add和remove同一变量来实现(如果此处调用了无参构造方法,需要在自定义类中再显式定义无参构造方法,因为前文已经定义了有参构造方法,没有默认无参构造方法)

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值