Java集合框架里List子接口的contains()和Remove()方法剖析

————————————————————————————————————————
———————————————————————

List框架内容可以看这篇文章,很不错

本文主要介绍一下:

关于ArrayList和LinkedList容器内部的
contains()方法 和 Remove()方法的内部实现机制。

总体来说就是:利用Object类的equals()方法。并进行重写;
通过两个小例子进行解释更清晰一些:

案例一:实现去除ArrayList容器内的重复元素。

import java.util.*;//引入java包

	public static ArrayList signalElements(ArrayList al)
	{
		//定义临时ArrayList容器
		ArrayList newal=new ArrayList();
		//遍历传入的集合
		Iterator it=al.iterator();

		while(it.hasNext())
		{
			Object obj=it.next();
			
//----------contains()方法使用的是obj的equals()方法!(先忽略)--------------------------

			if(!newal.contains(obj))
				newal.add(obj);
		}
		return newal;
	}
案例二:实现自定义对象存入到ArrayList容器中,并去除重复元素。

假设定义一个包含姓名和年龄的Person类

class Person
{
	private String name;
	private int age;
	//假设函数一初始化就指定姓名和年龄
	Person(String name,int age)
	{
		this.name = name;
		this.age = age;
	}
	//这里只写了get方法,用于获取。开发一般get和set都写
	public String getName()
	{
		return name;
	}
	public int getAge()
	{
		return age;
	}
}

主函数:

class CollectionListDemo 
{
	public static void main(String[] args) 
	{
		//创建一个ArrayList集合
		ArrayList al=new ArrayList();
		//添加元素
		
//------集合添加进去的实际上是一个地址值,并不是元素实体------------------------

		al.add(new Person("zhangsan01",20));
		al.add(new Person("lishi01",21));
		al.add(new Person("zhangsan01",22));
		al.add(new Person("lishi01",21));

//------实现取对象元素的属性,即姓名,年龄------------------------------------
//-------标签:001------这行等下要添加代码-----------------------------------
//-------标签:002------这行等下要添加代码-----------------------------------

		//创建迭代器
		Iterator it=al.iterator();
		while(it.hasNext())
		{
			System.out.println(it.next().getName()+"......"+it.next().getAge());
			/*
			这句话有两处错误:
				1.每使用一次it.next(),指针便会往下走,即获取到的是下一个元素。
			所以第一次打印的结果为zhangsan01这个姓名和lishi01的年龄21
				2.实际上这句话会直接报错。根本不会打印结果。原因:
			迭代器作为对集合遍历,由于集合内存入的元素类型并不一定相同。
			所以迭代器返回的结果为Object类型的,在使用it.next()时
			返回了一个Object类对象,但是Object对象并不存在getName()方法。
			而只有Person类才有该方法。所以涉及到多态:
			正确使用:
						Object obj = it.next();
						Person p = (Person)obj;
						System.out.println(p.getName()+"......"+p.getAge());
			*/
		}
	}
}
到这里我们仅仅实现了添加自定义对象。接下来实现去除重复值:

把案例一的代码拷贝到主函数所在类CollectionListDemo中。
并在主函数中加入:

al = signalElements(al);
位置:放在 “标签:001” 那里(找不到用Ctrl—F查找)
运行结果:
	zhangsan01......20
	lishi01......21
	zhangsan01......22
	lishi01......21
发现并没有去除掉重复元素。

查其原因即可明白,其一直都有走下面这句代码。

if(!newal.contains(obj))

我们再回去看ArrayList的add()方法:发现其实际存的是地址值。每new一个对象,就会开辟一块空间。就会有一个地址值。所以这四个加入的元素有四个不同的地址。而我们判断包含contains(),实际使用的是Object类的equals()方法(Object类的equals()比较的是地址值,地址相同才返回true,否则返回false)。所以上述操作并没有删除掉成功。

解决办法:
重写equals()方法。让其比较内部元素而不是地址值。

在Person类里重写Object的equals()方法

public boolean equals(Object obj)
	{
		if(!(obj instanceof Person))//防止你随便拿一个其他类,比如Student类来和Person类进行比较,没意义
			return false;
		Person p=(Person)obj;
		return this.name.equals(p.name)&&this.age==p.age;//这句话里的equals是String类的equals方法
	}

这个方法会被 contains() 方法自动调用。

jdk API里关于contains(Object o)方法的描述:

public boolean contains(Object obj)
//如果此列表中包含指定的元素,则返回 true。
更确切地讲,当且仅当此列表包含至少一个满足 (obj==null ? e==null : obj.equals(e)) 的元素 e 时,则返回 true。 

 A /
s
Tip:
看见里的 'A' 字符上面的 "obj" 了吗。再看案例一里面的contains()方法。就更容易明白了。

到这里,算是讲完了contains()方法,接下来看Remove()方法。

比如我们想要删除如下元素

zhangsan01......20

在”标签:002“那里写这句话

System.out.println("移除元素:"+remove(new Preson("zhangsan01",20)));
前提:把重写的equals()注释掉
运行结果为:
	移除元素:false

原因:移除的是个对象,利用Object类的equals()方法去判断地址值,找不到相同的地址值。所以不可能删掉。再把重写的equals()取消注释,就可以移除成功了。

下一篇:关于集合框架的Set接口的常用子接口的应用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值