集合的概念:
集合與數組的特點對比:
集合:數量不限、類型不限
數組:定長、類型單一
“集合框架”由一組用來操作對象的接口組成,不同接口描述不同類型的組
數據存儲結構分類:
(1)順序存儲 (2)鏈式存儲 (3)樹形存儲 (4)散列存儲Hash (5)Map映射存儲

接口 |
實現 |
歷史集合類 |
Set |
HashSet |
|
TreeSet |
||
List |
ArrayList |
Vector |
LinkedList |
Stack |
|
Map |
HashMap |
Hashtable |
TreeMap |
Properties |
集合框架中各接口的特點:
1:Collection接口 是一組允許重復的對象。
2:Set接口 繼承Collection,無序但不允許重復。
3:List接口 繼承Collection,有序但允許重復,並引入位置下標。
4:Map接口 既不繼承Set也不繼承Collection,是鍵值對。
Collection接口:
用於表示任何對象或元素組。想要盡可能以常規方式處理一組元素時,就使用這一接口。
方法摘要 | ||
---|---|---|
boolean |
add(E e) 確保此 collection 包含指定的元素(可選操作)。 |
|
boolean |
addAll(Collection<? extends E> c) 將指定 collection 中的所有元素都添加到此 collection 中(可選操作)。 |
|
void |
clear() 移除此 collection 中的所有元素(可選操作)。 |
|
boolean |
contains(Object o) 如果此 collection 包含指定的元素,則返回 true。 |
|
boolean |
containsAll(Collection<?> c) 如果此 collection 包含指定 collection 中的所有元素,則返回 true。 |
|
boolean |
equals(Object o) 比較此 collection 與指定對象是否相等。 |
|
int |
hashCode() 返回此 collection 的哈希碼值。 |
|
boolean |
isEmpty() 如果此 collection 不包含元素,則返回 true。 |
|
Iterator<E> |
iterator() 返回在此 collection 的元素上進行迭代的迭代器。 |
|
boolean |
remove(Object o) 從此 collection 中移除指定元素的單個實例,如果存在的話(可選操作)。 |
|
boolean |
removeAll(Collection<?> c) 移除此 collection 中那些也包含在指定 collection 中的所有元素(可選操作)。 |
|
boolean |
retainAll(Collection<?> c) 僅保留此 collection 中那些也包含在指定 collection 的元素(可選操作)。 |
|
int |
size() 返回此 collection 中的元素數。 |
|
Object[] |
toArray() 返回包含此 collection 中所有元素的數組。 |
|
|
toArray(T[] a) 返回包含此 collection 中所有元素的數組;返回數組的運行時類型與指定數組的運行時類型相同。 |
-
<pre name= "code" class="java">//可初定義容量大小為0
-
//Set是接口,必須new它的實現類
-
//HashSet是一組不
-
Set<Object> set= new HashSet<Object>(0);
-
Set<Object> set2= new HashSet<Object>(0);
-
Person p1= new Person("張三",20);
-
Person p2= new Person("李四",22);
-
Person p3= new Person("王五",24);
-
Person p4= new Person("Jack",30);
-
Person p5= new Person("Tom",20);
-
Person p6= new Person("Swite",13);
-
Person p7= new Person("Pick",16);
-
Person p8= new Person("錢七",32);
-
//添加元素,集合容量會增加(JAVA類中有操作),返回型boolean
-
//注意添加的是元素的地址,改變集合中的一個元素,另一集合的相同元素同樣改變
-
//添加順序是根據Hash算法排序的,因此需要實現添加元素的hashCode和equals函數
-
//不然按該元素的內存地址排序
-
set.add(p1);set2.add(p1);
-
System.out.println(set.add(p1)); //返回FALSE,已加入元素不會重復添加
-
set.add(p5);set2.add(p5);
-
set.add(p6);set2.add(p6);
-
set.add(p4);set2.add(p7);
-
set.add(p2);set2.add(p8);
-
set.add(p3);
-
//在set2中元素全部加入,有添加的元素,返回true
-
set.addAll(set2);
-
//將集合的所有元素清空
-
set.clear();
-
//判斷集合中有無此元素,有則返回true,
-
set.contains(p1);
-
//判斷集合set2中的元素是否在set集合中都有,返回boolean值
-
set.containsAll(set2);
-
//判斷參數對象與此對象的相等性
-
set.equals(p1); //false(即使集合中只有p1,也不會相等,因為是不同對象)
-
//若倆個集合中的元素相等,則倆個集合相等,
-
set.equals(set2); //false
-
//判斷集合是否是空
-
set.isEmpty();
-
//獲得集合元素的個數
-
set.size();
-
//移除集合的某一個元素,返回boolean值,沒有則返回false
-
set.remove(p1);
-
//移除既在參數集合中存在,又在此集合中存在的元素,取差集,返回值boolean值
-
set.removeAll(set2);
-
//移除不存在參數集合中的本集合元素,取交集,返回值boolean值
-
set.retainAll(set2);
-
//返回集合的迭代器,以便搜索集合的元素
-
//因為HashSet是按哈希值存儲,不便直接定位
-
Iterator<Object> it =set.iterator();
-
while(it.hasNext()){
-
//依次輸出集合的每一個元素的toString()
-
System.out.println(it.next());
-
}
2、Character 按Unicode值的數字大小排序
3、CollationKey 按語言環境敏感的字符串排序
4、Date 按年代排序
5、File 按系統特定的路徑名的全限定字符的Unicode值排序
6、ObjectStreamField 按名字中字符的Unicode值排序
7、String 按字符串中字符Unicode值排序
-
public class TreeSetDome {
-
-
public static void main(String[] args) {
-
<span style= "color:#ff0000;">//TreeSet具有set接口的所有函數(上面的函數)</span>
-
//在new時可以加入指定的比較器
-
TreeSet<Object> set= new TreeSet<Object>(new MyComp());
-
Person p1= new Person("張三",20);
-
//TreeSet具有其他函數
-
//返回此 set 中大於等於給定元素的最小元素;如果不存在這樣的元素,則返回 null
-
set.ceiling(p1);
-
//返回對此 set 中的元素進行排序的比較器;如果此 set 使用其元素的自然順序,則返回 null。
-
set.floor(p1);
-
//返回此 set 中嚴格大於給定元素的最小元素;如果不存在這樣的元素,則返回 null。
-
set.comparator();
-
//返回此 set 中當前第一個(最低)元素。
-
set.first();
-
//返回此 set 中當前最后一個(最高)元素。
-
set.last();
-
//返回此 set 中小於等於給定元素的最大元素;如果不存在這樣的元素,則返回 null。
-
set.higher(p1);
-
//返回此 set 中嚴格小於給定元素的最大元素;如果不存在這樣的元素,則返回 null。
-
set.lower(p1);
-
//獲取並移除第一個(最低)元素;如果此 set 為空,則返回 null。
-
set.pollFirst();
-
//獲取並移除最后一個(最高)元素;如果此 set 為空,則返回 null。
-
set.pollLast();
-
-
}
-
-
-
}
-
class MyComp implements Comparator<Object>{
-
-
-
public int compare(Object o1, Object o2) {
-
//返回值為負整數,0,正整數(int型)
-
//表示本對象比參數對象小,相等,大
-
return 1;
-
}
-
}
List接口繼承了Collection接口以定義一個允許重復項的有序集合。該接口不但能夠對列表的一部分進行處理,還添加了面向位置的操作。面向位置的操作包括插入某個元素或Collection的功能,還包括獲取、除去或更改元素的功能。在List中搜索元素可以從列表的頭部或尾部開始,如果找到元素,還將報告元素所在的位置。
1)使用List(如ArrayList)時,不會自動調用hashCode()方法。因為在List中,重復了就重復了,不需判斷,保證唯一性。
2)List中添加了下標index的功能,這樣對List的修改可以利用set方法對指定位置的元素直接進行替換,不需要象Set那么復雜(要轉換成數組才能修改,之后還要轉換回去)。
3)Collection用Iterator迭代器,而List可以用ListIterator列表迭代器。前者只能next(),后者不但包含next()方法,還包含previous()方法。因此,如果要用List做類似書的翻頁功能,不但可以向后翻,還可以向前翻。
-
package cn.hncu.collection;
-
-
import java.util.ArrayList;
-
import java.util.Iterator;
-
import java.util.ListIterator;
-
-
public class ArrayListDome {
-
-
public static void main(String[] args) {
-
//List接口引入了下標,並且可以添加重復的元素
-
ArrayList<Object> al1= new ArrayList<Object>(0);
-
ArrayList<Object> al2= new ArrayList<Object>(0);
-
Person p1= new Person("張三",20);
-
Person p2= new Person("李四",22);
-
Person p3= new Person("王五",24);
-
Person p4= new Person("Jack",30);
-
Person p5= new Person("Tom",20);
-
Person p6= new Person("Swite",13);
-
Person p7= new Person("Pick",16);
-
Person p8= new Person("錢七",32);
-
//添加時,根據下標位置排序,無需實現元素的hashCode和equals方法
-
//可以指定下標添加,但要注意,不能加入的下標大小比集合容量大,否則出異常
-
al1.add(p1);
-
al1.add( 0,p2);
-
al1.add(al1.size()- 1,p3);
-
al1.add(p4);
-
al1.add(p5);
-
al1.add( 0,p6);
-
al2.add(p2);
-
al2.add(p4);
-
al2.add(p6);
-
al2.add(p8);
-
-
//可以添加其他集合的指定位置
-
al1.addAll( 0, al2);
-
//返回此列表中指定位置上的元素。
-
al1.get( 0);
-
//返回此列表中首次出現的指定元素的索引,或如果此列表不包含元素,則返回 -1。
-
al1.indexOf(p1);
-
//返回此列表中最后一次出現的指定元素的索引,或如果此列表不包含索引,則返回 -1。
-
al1.lastIndexOf(p1);
-
//移除此列表中指定位置上的元素。
-
al1.remove( 0);
-
//用指定的元素替代此列表中指定位置上的元素。
-
al1.set( 0, p2);
-
//按適當順序(從第一個到最后一個元素)返回包含此列表中所有元素的數組。
-
al1.toArray();
-
//按適當順序(從第一個到最后一個元素)返回包含此列表中所有元素的數組;返回數組的運行時類型是指定數組的運行時類型。
-
Person[] a = new Person[0];
-
a=al1.toArray(a);
-
//將此 ArrayList 實例的容量調整為列表的當前大小。
-
al1.trimToSize();
-
//返回列表中索引在 fromIndex(包括)和 toIndex(不包括)之間的所有元素組成一個新的集合列表。
-
al1.subList( 0, 1);
-
-
-
-
//返回此 ArrayList 實例的淺表副本。只是復制了指針,倆個集合共用元素
-
ArrayList<Object> po=(ArrayList<Object>) al1.clone();
-
((Person)al1.get( 0)).age=10000;
-
((Person)al2.get( 0)).age=-300;
-
for (int i = 0; i < po.size(); i++) {
-
System.out.println(po.get(i));
-
}
-
//返回列表的迭代器
-
ListIterator it=al1.listIterator();
-
while(it.hasNext()){
-
System.out.println(it.next()); //當前的下一個
-
System.out.println(it.previous()); //當前的上一個
-
}
-
-
}
-
-
}
如果要支持隨機訪問,而不必在除尾部的任何位置插入或除去元素,那么,ArrayList提供了可選的集合。(查找)
但如果要頻繁的從列表的中間位置添加和除去元素,而只要順序的訪問列表元素,那么LinkedList實現更好(添加,刪除)-
//構造空的
-
LinkedList list= new LinkedList();
-
-
Person p1= new Person("張三",20);
-
-
<span style= "color:#ff0000;">//鏈表也具有排序和下標功能,ArrayList的函數</span>
-
//將指定元素插入此列表的開頭。
-
list.addFirst(p1);
-
list.offerFirst(p1);
-
//將指定元素添加到此列表的結尾。
-
list.addLast(p1);
-
list.offer(p1);
-
list.offerLast(p1);
-
// 獲取但不移除此列表的頭(第一個元素)。
-
list.element();
-
list.get( 0);
-
list.getFirst();
-
list.peek();
-
list.peekFirst(); //沒有返回空
-
//獲取並移除此列表的頭(第一個元素)
-
list.pop();
-
list.pollFirst(); //沒有返回空
-
list.remove( 0);
-
list.removeFirst();
-
//移 不移除列表的尾而獲得同頭部;
-
list.peekLast();
-
list.getLast();
-
-
list.pollLast();
-
list.removeLast();
-
//從此列表中移除第一次出現的指定元素(從頭部到尾部遍歷列表時)。
-
list.removeFirstOccurrence(p1);
-
//從此列表中移除最后一次出現的指定元素(從頭部到尾部遍歷列表時)。
-
list.removeLastOccurrence(p1);
-
ArrayList<Object> al= new ArrayList<Object>(0);
-
-
public void push(Object obj){
-
al.add(obj);
-
}
-
public Object pop(){
-
if(!al.isEmpty())
-
return al.remove(0);
-
return null;
-
}
-
-
public boolean isEmpty(){
-
return al.isEmpty();
-
}
-
ArrayList<Object> al= new ArrayList<Object>(0);
-
-
public void push(Object obj){
-
al.add(obj);
-
}
-
public Object pop(){
-
if(!al.isEmpty())
-
return al.remove(al.size()-1);
-
return null;
-
}
-
-
public boolean isEmpty(){
-
return al.isEmpty();
-
}
-
LinkedList<Object> lkl= new LinkedList<Object>();
-
-
public void push(Object obj){
-
lkl.add(obj);
-
}
-
public Object pop(){
-
return lkl.poll();
-
}
-
-
public boolean isEmpty(){
-
return lkl.isEmpty();
-
}
-
LinkedList<Object> lkl= new LinkedList<Object>();
-
-
public void push(Object obj){
-
lkl.add(obj);
-
}
-
public Object pop(){
-
return lkl.pollLast();
-
}
-
-
public boolean isEmpty(){
-
return lkl.isEmpty();
-
}
可以把這個接口方法分成三組操作:改變、查詢和提供可選視圖。
改變操作允許從映射中添加和除去鍵-值對。鍵和值都可以為null。但是,不能把Map作為一個鍵或值添加給自身
-
HashMap<String, Object> map= new HashMap<String, Object>(0);
-
Person p1= new Person("張三",20);
-
Person p2= new Person("李四",22);
-
Person p3= new Person("王五",24);
-
Person p4= new Person("Jack",30);
-
Person p5= new Person("Tom",20);
-
Person p6= new Person("Swite",13);
-
-
//鍵-值添加,put函數
-
map.put( "1001", p1);
-
map.put( "1002", p2);
-
map.put( "1003", p3);
-
map.put( "1004", p4);
-
map.put( "1005", p5);
-
map.put( "1006", p6);
-
//返回指定鍵所映射的值;如果對於該鍵來說,此映射不包含任何映射關系,則返回 null。
-
map.get( "1001");
-
//從此映射中移除指定鍵的映射關系(如果存在)。
-
map.remove( "1001");
-
//移除集合
-
map.clear();
-
//entry視圖
-
Set<Map.Entry<String, Object>> entry=map.entrySet();
-
Iterator<Map.Entry<String, Object>> it=entry.iterator();
-
while(it.hasNext()){
-
Map.Entry<String, Object> en=it.next();
-
System.out.println(en.getKey()+ " "+en.getValue());
-
}
-
System.out.println( "------------------");
-
//key視圖
-
Set<String> keys=map.keySet();
-
Iterator<String> it2=keys.iterator();
-
while(it2.hasNext()){
-
String str=it2.next();
-
System.out.println(str+ " "+map.get(str));
-
}
-
System.out.println( "------------------");
-
//values視圖(不常用)
-
Collection<Object> values=map.values();
-
Iterator<Object> it3=values.iterator();
-
while(it3.hasNext()){
-
Object obj=it3.next();
-
System.out.println(obj);
-
}
“集合框架”提供兩種常規的Map實現:HashMap和TreeMap。和所有的具體實現一樣,使用哪種實現取決於特定需要。
在Map中插入、刪除和定位元素,HashMap是最好的選擇。但如果要按順序遍歷鍵,那么TreeMap會更好。
使用HashMap要求添加的鍵類明確定義了hashCode()實現(助理解:Map.keySet返回的是鍵的Set集合,而Set集合對hashCode實現有限制,因此作為鍵的類也要遵守該限制)。有了TreeMap實現,添加到映射的元素一定是可排序的。
中文排序問題比較函數對於英文字母與數字等ASCII碼中的字符排序都沒問題,但中文排序則明顯不正確。這主要是Java中使用中文編碼GB2312或GBK時,char型轉換成int型的過程出現了比較大的偏差。這偏差是由compare方法導致的,因此我們可以自己實現Comparator接口。另外,國際化問題可用Collator類來解決。
java.text.Collator類,提供以與自然語言無關的方式來處理文本、日期、數字和消息的類和接口。