————————————————————————————————————————
———————————————————————
本文主要介紹一下:
關於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()取消註釋,就可以移除成功了。