1. 程式人生 > >Java 集合類常用方法

Java 集合類常用方法

cti unknown nag ace 方法區 中比 thread arr 使用

Collection中的contains()方法和remove()方法。

boolean contains(Object o);該方法是用來判斷集合中是否包含某個元素,若包含,返回true,不包含返回false。結合以下代碼來看。

import java.util.*;
public class CollectionTest03{
public static void main(String[] args){
Collection c=new ArrayList();
Integer i1=new Integer(10);
c.add(i1); //true
System.out.println(c.contains(i1));
Integer i2=new Integer(10);
//contains()方法底層調用的是equals()方法
c.contains(i2); //true
System.out.println(c.contains(i1));

Manager m1=new Manager(100,"張三");
c.add(m1);
System.out.println(c.contains(m1)); //true
Manager m2=new Manager(100,"張三");
System.out.println(c.contains(m2)); //false
}

/* 底層源碼
public boolean contains(Object i2) {
return indexOf(i2) >= 0; //indexOf(i2) >= 0; 結果為true or false,即 return true(or false)
}
public int indexOf(Object i2) {
if (i2 == null) {
//i2為空值時與ArrayList中的元素進行比較
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i; //此時i>=0
} else {
//i2不為空值時與ArrayList中的元素進行比較
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i; //i>=0
}
return -1;
}
*/
}
class Manager{
int no;
String name;
Manager(int no,String name){
this.no=no;
this.name=name;
}
}

運行後輸出:

true
true
true
false

上述代碼中,

1.創建集合對象c,之後Integer i1=new Integer(10);new出一個Integer類型的對象,使用c.add(i1);將i1添加到集合c中,最後使用c.contains(i1);判斷集合c中是否包含i1並將結果打印。

2.Integer i2=new Integer(10);再new出一個Integer類型的對象i2,並且和i1相同,System.out.println(c.contains(i2));判斷集合c是否包含i2並將結果打印,註意,這裏沒有第一步中的c.add()方法,但結果依舊輸出true。這是因為contains()方法底層調用的了equals()方法。這裏我們打開jdk的幫助文檔來看底層的源碼。

public boolean contains(Object i2) {
return indexOf(i2) >= 0; //indexOf(i2) >= 0; 結果為true or false,即 return true(or false)
}
public int indexOf(Object i2) {
if (i2 == null) {
//i2為空值時與ArrayList中的元素進行比較
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i; //此時i>=0
} else {
//i2不為空值時與ArrayList中的元素進行比較
for (int i = 0; i < size; i++)
if (i2.equals(elementData[i]))
return i; //i>=0
}
return -1;
}

從底層源碼中可以看出,contains()方法中調用了indexOf()方法,

public boolean contains(Object i2) {

return indexOf(i2) >= 0;

}

indexOf(i2) >= 0; i>=0時,結果為true,否則為false,即 return true(or false)

接下來具體看看indexOf()方法,i2可能為空值,也可能不為空,當i2為空值時,與Arraylist中的元素進行比較,使用for循環對ArrayList中的元素進行遍歷,若elementData[i]==null,即在ArrayList中找到了與i2一樣都為null的元素,則返回此時ArrayList中的索引,我們知道索引都是>=0的,即contains()方法中return true.當i2不為空值時,仍然使用for循環進行遍歷ArrayList()中的元素,如果發現i2與ArrayList中的某個元素相等,則返回ArrayList中該元素的索引下標,同理,contains()方法中return true。如果這兩種情況都不滿足,也就意味著i2與ArrayList中的元素都不相等,這時return -1,contains()方法中return false。

3.接下來我們自定義一個Manager的類,Manager m1=new Manager(100,"張三");創建一Manager類型的的對象m1,c.add(m1);將m1添加到ArrayList中,使用contains()方法判斷集合c中是否包含m1;接著Manager m2=new Manager(100,"張三");new出一個對象m2,添加到集合c中,使用contains()方法進行判斷時輸出false,這時因為m1和m2都是new出來的對象,它們的內存地址不相同,Manager類中沒有重寫equals()方法,所以進行判斷時比較的還是內存地址,返回結果為false。

4.如果要在Manager類中比較內容而不是內存地址,我們可以這樣重寫Manager中的equals()方法。

public boolean equals(Object o){
if (this == o) return true;
if (o instanceof Manager){
Manager m = (Manager)o;
if(m.no==this.no && m.name==this.name){
return true;
}
}
return false;
}

這裏要註意:存儲在集合中的元素應該重寫equals()方法。重寫Manager中的equals()方法後System.out.println(c.contains(m2));打印出結果為true。

接下來看remove()方法。

boolean remove(Object o); 刪除集合中某個元素

看以下代碼:

import java.util.*;
public class CollectionTest04{
public static void main(String[] args){
Collection c=new ArrayList();
Integer i1=new Integer(10);
c.add(i1);
System.out.println(c.size()); //1
Integer i2=new Integer (10);
c.remove(i2);
System.out.println(c.size()); //0
Manager m1=new Manager(100,"張三");
c.add(m1);
Manager m2=new Manager(100,"張三");
c.remove(m2);
System.out.println(c.size()); //0
}
}
class Manager{
int no;
String name;
Manager(int no,String name){
this.no=no;
this.name=name;
}
public boolean equals(Object o){
if (this == o) return true;
if (o instanceof Manager){
Manager m = (Manager)o;
if(m.no==this.no && m.name==this.name){
return true;
}
}
return false;
}
}

理解了contains()方法中講的知識點,remove()中的應該很容易就能判斷出該輸出什麽,這裏就不詳細地再進行講解了。不過提醒一點,如果數據在[-128~127]之間,Java中引入了一個“整型常量池”,在方法區中。該整型常量池只存儲-128~127之間的數據。Integer i5=127;這個程序不會在堆中創建對象,會直接在整型常量池中拿。這是之前講的內容,忘記了的翻到之前的《Java 包裝類詳解》再復習一遍。

深入remove()方法。

import java.util.*;
public class CollectionTest05{
public static void main(String[] args){
Collection c=new ArrayList();
c.add(1);
c.add(2);
c.add(3);
Iterator it=c.iterator();
while (it.hasNext()){
it.next();
it.remove(); //通過叠代器的remove()方法刪除元素
}
System.out.println(c.size()); //0
}
}

以上程序為使用叠代器的remove()方法刪除,當使用集合的remove()方法刪除時,如下:

import java.util.*;
public class CollectionTest05{
public static void main(String[] args){
Collection c=new ArrayList();
c.add(1);
c.add(2);
c.add(3);
Iterator it=c.iterator();
while (it.hasNext()){
Object element=it.next();
c.remove(element); //使用集合的remove()方法刪除
}
System.out.println(c.size());
}
}

編譯通過,運行後報錯:

Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at CollectionTest05.main(CollectionTest05.java:25)

這是因為使用集合Collection的remove()方法進行刪除時,c.remove(element);也就是刪除一個元素之後,這個集合已經變了,再進行刪除元素的動作時,必須重新獲取改變之後的集合的叠代器,否則運行後報異常。所以推薦使用叠代器的remove()方法進行元素的刪除。

Java 集合類常用方法