Arrays數組類 & 集合類Collection
-
內存層面需要針對多個數據進行存儲,此時可以考慮的容器有:數組,集合類
-
數組Arrays介紹:
數組存儲多個數據方面的特點:
數組一旦初始化,其長度是確定的。
數組中的多個元素是依次緊密排列的,有序的,可重復的
(優點) 數組一旦初始化完成,其元素的類型就是確定的,不是此類型的元素,就不能添加到此數組中。
(優點)元素的類型既可以是基本數據類型,也可以是引用數據類型
舉例
// 基本數據類型舉例
int [] arr = new int[10];
arr[0]=1;
arr[1]="AA";//編譯會報錯
上面這種情況使用String [] 但是又不能輸入int數值類型。// 只能使用下面這種引用數據類型
Object [] arr1 = new Object[10];
arr1[0]=new String; //既可以放String
arr1[1]=new Date; //也可以放Date
數組存儲多個數據方面的弊端:
數組一旦初始化,其長度就不可變了
數組中存儲數據特點的單一性。對于無序的,不可重復的場景的多個數據就無能為力了。
數組中可用的方法屬性都極少。具體的需求都需要自己來組織相關的代碼邏輯。
針對數組中元素的刪除、插入操作,性能較差。
- Collection集合介紹
Collection集合類
Java集合框架體系(java.util包下)
java.util.Collection:集合類,存儲一個一個的數據
|----- 子接口:List:存儲有序的,可重復的數據(List可以看成是“動態”數組)
|------ArrayList(這個用得多,主要實現類), LInkedList, Vector
|----- 子接口:Set:存儲無序的,不可重復的數據(類似數學里說的集合,里面元素是亂的)
|------HashSet, LinkedHashSet,TreeSet
java.util.Map: 存儲一對一對的數據(key-value鍵值對,(x1,y1),(x2,y2) --> y=f(x),類似于高中的函數,不同的key可以指向同一個value,同一個key不能指向多個value)
|------HashMap,LinkedHashMap,TreeMap,Hashtable,Properties
- 集合常用方法(Collection中定義了15個抽象方法,這些方法需要大家熟悉)
add(Object obj)
addAll(Collection coll)
clear()
isEmpty()
size()
contains(Object obj)
containsAll(Collection coll)
retainAll(Collection coll)
remove(Object obj)
removeAll(Collection coll)
hashcode()
equals()
toArray()
注:iterator()下一章講
下面來舉例他們的具體使用:
* 1.add(Object obj):添加元素對象到當前集合中
* 2.addAll(Collection other):添加other集合中的所有元素對象到當前集合中,即this = this U other
應用舉例
package Collection;import org.junit.Test;
import java.util.*;public class CollectionTest {/** 1.add(Object obj):添加元素對象到當前集合中* 2.addAll(Collection other):添加other集合中的所有元素對象到當前集合中,即this = this U other** */@Testpublic void test(){Collection coll = new ArrayList();coll.add("AA");coll.add(123);//自動裝箱coll.add("haha");coll.add(new Object());coll.add(new Person("Tome",12));System.out.println(coll+"\n"+"-------->");System.out.println(coll.size());Collection coll1 = new ArrayList();coll1.add("BB");coll1.add(456);//自動裝箱//coll.addAll(coll1);//size為5+2=7coll.add(coll1);//將coll1整體看成一個元素,加在后面,所以此時size為5+1=6System.out.println(coll);//size()System.out.println(coll.size());}
運行結果
[AA, 123, haha, java.lang.Object@1ef7fe8e, Person{name='Tome', age=12}]
-------->
5
[AA, 123, haha, java.lang.Object@1ef7fe8e, Person{name='Tome', age=12}, [BB, 456]]
6
* 3. int size() 獲取當前集合中實際存儲的元素個數
* 4. boolean isEmpty() 判斷當前集合是否為空集合
* 5. boolean contains(Object obj) 判斷當前集合中是否存在一個與obj對象equals返回true的元素
應用舉例
package Collection;import org.junit.Test;
import java.util.*;public class CollectionTest {@Testpublic void test2(){Collection coll = new ArrayList();//add()coll.add("AA");coll.add(123);//自動裝箱Person p1 = new Person("Tom",12);coll.add(p1);coll.add(new String("haha"));//coll.add(new Person("Tom",12));//isEmpty()System.out.println("coll是空的嗎? "+coll.isEmpty());//contains()System.out.println(coll.contains("AA"));//結果為AASystem.out.println(coll.contains(123));//結果為true說明比較的不是地址,而是單純的比較內容是否一致System.out.println(coll.contains(new String("haha")));//結果為trueSystem.out.println("coll內容里有person的p1嗎?"+coll.contains(p1));//結果為trueSystem.out.println(coll.contains(new Person("Tom", 12))); //如果Person內equals方法不做任何重寫,結果會為false,原因如下// 因為Person里面沒有重寫equals方法,那么這里的contains做比較,用的是Object里面的equals,也就是==比較的是兩個引用是否指向內存中的同一個對象,這里是兩個對象,所以得到false// 一般來說,contains比較,用的就是equals方法,主要比對的就是內容是否一致。對于自定義類例如Person,如果將來想要使用contains方法做內容比較,通常會在Person內部自己重寫equals方法。
如果Person內equals方法重寫后,結果為true。}
}
運行結果:
coll是空的嗎? false
true
true
true
現在調用person.equals方法啦
現在調用person.equals方法啦
現在調用person.equals方法啦
coll內容里有person的p1嗎?true
現在調用person.equals方法啦
現在調用person.equals方法啦
現在調用person.equals方法啦
true
問題:上述【現在調用person.equals方法啦】出現了三次然后才顯示【coll內容里有person的p1嗎?true】為什么會出現三次,怎么理解?
回答:因為上面coll定義的是一個new ArrayList(),而當判斷“coll.contains”就需要調用這個元素p1所屬 Person類的equal方法,而在Person類中用戶定義的equals里面需要的行參是(Object o),這里就是coll,自然需要將coll里面的元素一個一個送進去都比對一遍,先是“AA”然后123然后才能輪到Person類的p1元素,所以調用了三次才出現的結果。
* 6. boolean containsAll(Collection coll):判斷coll集合中的元素是否是在當前集合中都存在。即coll
* 7. boolean equals(Object obj) 判斷當前集合與obj是否相等,注意必須是兩個完全相同的集合(這個用的較少,了解一下)
應用舉例
package Collection;import org.junit.Test;
import java.util.*;public class CollectionTest {@Testpublic void test03(){Collection coll = new ArrayList();coll.add("AA");coll.add(123);//自動裝箱coll.add(new Person("Tom",12));coll.add(new String("haha"));Collection coll1 = new ArrayList();coll1.add("AA");coll1.add("BB");System.out.println(coll.containsAll(coll1));Collection coll2 = new ArrayList();coll2.add("AA");System.out.println(coll.containsAll(coll2));}}
運行結果:
false
trueProcess finished with exit code 0
/*
* 8. void clear(): 清空集合元素
* 9. boolean remove(Object obj)從當前集合中刪除第一個找到的與obj對象equals返回true的元素
* 10. boolean removeAll(Collection coll) 從當前集合中刪除所有與coll集合中相同的元素,即this = this - this ? coll
* 11. boolean retainAll(Collection coll) 從當前集合中刪除兩個集合中不同的元素。使得當前集合僅僅保留與coll集合中元素相同的元素。也就是僅僅保留兩個集合的交集,this = this ? coll
*
* */
package Collection;import org.junit.Test;
import java.util.*;public class CollectionTest {@Testpublic void test03_1() {Collection coll = new ArrayList();coll.add("AA");coll.add("AA");//這里裝進去"AA"X2coll.add(123);//自動裝箱coll.add(new Person("Tom", 12));coll.add(new String("haha"));//coll.clear();coll.remove("AA");//依次刪掉一個“AA”,如果原來有兩個“AA”,那么還會剩一個//remove的刪除方法實際是:求size之后,一個個把元素改為null,并不是直接把size改成0完事(如果直接不管那些元素,等著下次直接有data直接再覆蓋,會造成內存泄漏)//第一種刪除Person的方法//Person p1 = new Person("Tom",12);//coll.remove(p1);//第二種刪除Person的方法coll.remove(new Person("Tom",12));System.out.println(coll);Collection coll1 = new ArrayList();coll1.add("AA");coll1.add(123);coll1.add("BB");System.out.println("coll="+coll);System.out.println("coll1="+coll1);//coll.removeAll(coll1);//刪除coll里面出現的coll1所有元素//System.out.println("刪除coll里面出現的coll1所有元素"+coll);System.out.println("------>");coll.retainAll(coll1);//保留coll 和 coll1的相同元素System.out.println("保留coll 和 coll1的相同元素"+coll);}}
運行結果:
現在調用person.equals方法啦
現在調用person.equals方法啦
現在調用person.equals方法啦
[AA, 123, haha]
coll=[AA, 123, haha]
coll1=[AA, 123, BB]
------>
保留coll 和 coll1的相同元素[AA, 123]Process finished with exit code 0
/*
* 12 Object[]toArray() 集合轉化成數組(也就是:返回包含當前集合中所有元素的數組)
* 13 hashCode() 獲取集合對象的哈希值
* 14 iterator() 返回迭代器對象,用于集合遍歷(下一章講)
* */
package Collection;import org.junit.Test;
import java.util.*;public class CollectionTest {@Testpublic void test04(){Collection coll = new ArrayList();coll.add("AA");coll.add("AA");//這里裝進去"AA"X2coll.add(123);//自動裝箱coll.add(new Person("Tom", 12));coll.add(new String("haha"));//集合 --> 數組Object [] arr = coll.toArray();System.out.println(Arrays.toString(arr));System.out.println(coll.hashCode());//求得hash碼}
}
運行時得
[AA, AA, 123, Person{name='Tom', age=12}, haha]
2095848593Process finished with exit code 0
- 集合數組的相互轉換
集合 —> 數組:toArray()
比如Object [] arr = coll.toArray();
數組 —> 集合:調用Arrays的靜態方法asList(Object … objs)
比如Collection list = Arrays.asList(arr);
應用舉例
package Collection;import org.junit.Test;
import java.util.*;public class CollectionTest {@Testpublic void test04(){Collection coll = new ArrayList();coll.add("AA");coll.add("AA");//這里裝進去"AA"X2coll.add(123);//自動裝箱coll.add(new Person("Tom", 12));coll.add(new String("haha"));//集合 --> 數組Object [] arr = coll.toArray();System.out.println(Arrays.toString(arr));System.out.println(coll.hashCode());//求得hash碼}@Testpublic void test5(){String[] arr = new String[]{"AA","BB","CC"};//數組-->集合// List list = Arrays.asList(arr); List或者Collection都行Collection list = Arrays.asList(arr);System.out.println(list);//數組轉成集合的方式,也可以直接在括號里面建立數組//注:寫了代碼Arrays.asList("AA","BB","CC","DD");后// 按alt+enter能快速補全需要的其他相關代碼,比如List list1 =List list1 = Arrays.asList("AA", "BB", "CC", "DD");System.out.println(list1);}}
test4運行結果
[AA, AA, 123, Person{name='Tom', age=12}, haha]
2095848593Process finished with exit code 0
test5運行結果
[AA, BB, CC]
[AA, BB, CC, DD]Process finished with exit code 0
問題:下面的test6里面list和list1的size分別是多少?為什么?
package Collection;import org.junit.Test;
import java.util.*;public class CollectionTest {@Testpublic void test6(){Integer[] arr = new Integer[]{1,2,3};List list = Arrays.asList(arr);System.out.println("list size is "+list.size()); //這里應該得到3,因為Arrays.asList(Object)里面加的是Object,所以這里是3個Integer包,裝了3個箱System.out.println(list);int[] arr1 = new int[]{1,2,3};List list1 = Arrays.asList(arr1);System.out.println("list1 size is "+list1.size());//這里應該得到1,因為Arrays.asList(Object)里面加的是Object,3個int被裝了一個箱送進去的System.out.println(list1);}}
運行結果:
list size is 3
[1, 2, 3]
list1 size is 1
[[I@5fe5c6f]Process finished with exit code 0
結果分析:
Arrays.asLis(Object obj)
由于只能放Object,所以遇見int系統會自動裝箱。
Integer[] arr = new Integer[]{1,2,3};
放進Arrays.asList時候按照3個箱放進去的,size得到3
int[] arr1 = new int[]{1,2,3};
放進Arrays.asList時候自動將幾個int裝一個箱放進去的,size得到1
- 向Collection中添加元素的要求:
要求元素所屬的類一定要重寫equals()
原因:因為Collection中的相關方法(比如:contains()/remove())在使用時,要調用元素所在類的equals().
- 學習的程度把握
層次一:針對于具體特點的多個數據,知道選擇相應的適合的接口的主要實現類,會實例化,會調用常用的方法。
層次二:區分接口中不同的實現類的區別。
層次三:1-針對于常用的實現類,需要熟悉底層的源碼 2-熟悉常見的數據結構(后面講“常用的數據結構”)