List集合中remove方法的使用

以ArrayList为例:

//泛型为引用数据类型:
ArrayList<String> list=new ArrayList<String>();
	list.add("tom");		
	list.add("jim");
	list.remove("jim");	//调用删除方法
	System.out.println(list.size());
	//删除的时候调用ArrayList中的remove方法,形参o为Object数据类型的,传入的o是String类型的,所以o为上转型对象,o的值不为空,执行else中的代码,o.equals(elementData[index]是o调用equals方法,Object类中的equals对于String类型来说是比较地址,传入的是jim对象,数组中有jim,所以删除成功。
	//ArrayList中remove方法的底层代码为
	/*
	public boolean remove(Object o) {	//形参o为Object数据类型的,传入的o是String类型的,所以o为上转型对象,传入的o的值不为空,执行else中的代码.
    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])) {	//o.equals(elementData[index]是o调用equals方法,elementData[index]是要遍历的集合中的元素。只有找到相同的内容才能执行下边的内容,如果没有的话进入下一次循环
                fastRemove(index);
                return true;
            }
    }
    return false;		//遍历完都没有找到匹配的内容才会执行此语句。
  }
  */	
  //Object中的equals方法为
	public boolean equals(Object obj) {
        return (this == obj);		//谁调用equals方法,this就可以指代谁,这里this指代jim。
    }
    //Object类中的equals对于String类型来说是比较内容是否相同,传入的是jim对象,数组中存在jim,所以会删除成功。

泛型为基本数据类型(以int为例):

	ArrayList<Integer> list=new ArrayList<Integer>();
	list.add(1);
	list.add(2);
	list.remove(1);		//删除,Integer类型(基本数据类型对应的包装类)比较数值是否相同。
	System.out.println(list.size());		//集合中的元素是按顺序排列的,remove(i)中的i指的是元素位置,执行删除语句后,集合后边的元素向前移。

泛型为Person类时:

	(1)
	ArrayList<Person> list=new ArrayList<Person>();//按顺序排列
	Person person=new Person();
	list.add(person);
	list.remove(person);	//删除,比较地址是否相同。同一个对象地址相同,删除的是同一个人,会删除成功。
	System.out.println(list.size());
	//此处调用remove方法后,执行调用equals方法的语句,如果在Person类中重写了equals方法,则调用的是子类重写后的方法:	
	public boolean equals(Object obj) {
		return super.equals(obj);	//此处比较的是地址。	
	}
	
	(2)
	ArrayList<Person> list=new ArrayList<Person>();
	list.add(new Person());//添加一个人
	list.add(new Person());//再添加一个人
	list.remove(new Person());//删除,引用数据类型比较地址是否相同,此处删除的又是另一个对象的地址,删除不成功。
	System.out.println(list.size());
	//此处重写equals方法后,调用的是子类重写后的方法:
	public boolean equals(Object obj) {
		return super.equals(obj);	//此处比较的是地址。	
	}
	
	(3)
	ArrayList<Person> list=new ArrayList<Person>();
	list.add(new Person("1"));
	list.add(new Person("2"));
	Person p=new Person("1");
	list.remove(p);
	System.out.println(list.size());//删除成功了,因为重写父类的equals方法,返回值改为return this.id.equals(person.id);		特别注意;比较的是id。
	
	//验证:
	System.out.println(list.get(0));//获取第一个j集合元素地址。
	System.out.println(list.get(0).id);//获取第一个集合元素id;

	//下边为Person类中重写的equals方法:出现多态,此处有明显重写了返回值比较规则。
	@Override	
public boolean equals(Object obj) {
	Person person=(Person)obj;	//上转型对象下转型后就可以调用子类新增的属性了。
	return this.id.equals(person.id);//判断传入的对象的id和集合中的对象的id是否相同。注意比较的是id,不是父类中的地址。
}

	(4)
	a,	泛型为Object时:传入的数据类型多种多样。
	b,	id为int类型
	c,	重写后的方法是:
	@Override	
	public boolean equals(Object obj) {
		Person person=(Person)obj;		//上转型对象下转型后就可以调用子类新增的属性了。
		return this.id.equals(person.id);
	}


	ArrayList<Object> list=new ArrayList<Object>();
	
	list.add(new Person(1));	
	list.add(new Dog(1));//不出错,第一行代码执行equals时地址正确,直接return结束,第二行代码不会执行。	
	Person p=new Person(1);
	list.remove(p);
	System.out.println(list.size());
	
	list.add(new Dog(1));	//出错。是因为类型转换错误,怎么解决?	见(5)
	list.add(new Person(1));
	Person p=new Person(1);
	list.remove(p);
	System.out.println(list.size());

	(5)
	a,	泛型为Object时:传入的数据类型多种多样。
	b,	id为int类型
	c,	重写后的方法是:
	@Override
	public boolean equals(Object obj) {
		if(obj instanceof Person) {		//instanceof是判断obj(实际传入的是person)指向的对象是否是Person类,或者Person类·的子类,或者是Person类的接口实现类创建的对象。
			Person person=(Person)obj;
			return this.id==(person.id);
		}
		return false;
	}
	改进重写方法之后不会出错了。因为首先判断不通过。

猜你喜欢

转载自blog.csdn.net/YXX_decsdn/article/details/89576807