申明:
實習生的膚淺了解,如發現有錯誤之處,還望大牛們多多指點
廢話
其實我寫java的背景操作,我每次都會遇到一條語句:List<XXXXX> list = new ArrayList<XXXXX>();
但是我僅僅隻是了解,list這個類是一個可變長用來存儲的對象執行個體的類,我甚至覺得這個List對象可以了解成數組,但是卻又與java中咱們正常了解的數組很多的不同,比如說,他的長度可以随着需要自動增長,比如說,執行個體化一個List類就和咱們聲明數組的時候是不一樣的!
今天的實習生活過的有點枯燥,我就打開了eclipse,看同僚們寫的代碼,無意間又看到了這句話,是以決定學習一下這一類的操作——java中的容器類(集合類)
正文
先偷個圖來吧,我不會告訴你我是在百度百科裡面偷的
如何,我們可以看出,java中的集合操作主要有兩大類:Collection集合與Map映射Collection
Collection是一個頂層的接口,他是java集合的一個抽象,在此基礎上派生出了兩個子接口,分别為:List與Set
List
List接口,特點有序的,所存儲的對象可以為null,并且允許重複,這點與set有很大差別,Set是不允許重複的,List很類似于數組,對于List對象的通路可以通過類似于數組下标去通路,但是是通過get(int index)方法進行通路的,同時其實際長度也很類似于數組,可以通過size()傳回其實際長度 ,除了具有Collection接口必備的iterator()方法外,List還提供一個listIterator()方法,傳回一個 ListIterator接口,和标準的Iterator接口相比,ListIterator多了一些add()之類的方法,允許添加,删除,設定元素,還能向前或向後周遊。 list常見方法::向清單的尾部添加指定的元素
add(E e)
: 在清單的指定位置插入指定元素
add(int index,E element)
:添加指定 collection 中的所有元素到此清單的結尾,順序是指定 collection 的疊代器傳回這些元素的順序
addAll(Collection<? extendsE> c)
: 将指定 collection 中的所有元素都插入到清單中的指定位置 與數組相比較,list的查詢效率 高,但是插入和删除的效率較低,因為插入和删除會引起其他元素的位置變化
addAll(int index,Collection<? extends E> c)
:從清單中移除所有元素
clear()
:如果清單包含指定的元素,則傳回true
contains(Object o)
:如果清單包含指定 collection 的所有元素,則傳回true
containsAll(Collection<?> c)
: 傳回清單中指定位置的元素
get(int index)
:傳回此清單中第一次出現的指定元素的索引;如果此清單不包含該元素,則傳回 -1
indexOf(Object o)
: 傳回按适當順序在清單的元素上進行疊代的疊代器
iterator()
:傳回此清單中最後出現的指定元素的索引;如果清單不包含此元素,則傳回 -1
lastIndexOf(Object o)
:傳回此清單元素的清單疊代器(按适當順序)
listIterator()
:傳回清單中元素的清單疊代器(按适當順序),從清單的指定位置開始
listIterator(int index)
: 移除清單中指定位置的元素
remove(int index)
:從此清單中移除第一次出現的指定元素
remove(Object o)
: 從清單中移除指定 collection 中包含的其所有元素
removeAll(Collection<?> c)
: 僅在清單中保留指定 collection 中所包含的元素
retainAll(Collection<?> c)
:用指定元素替換清單中指定位置的元素
set(int index,E element)
:傳回清單中的元素數
size()
傳回清單中指定的fromIndex(包括 )和 toIndex(不包括)之間的部分視圖
subList(int fromIndex,int toIndex)
toArray()
:傳回按适當順序包含清單中的所有元素的數組
詳細方法資訊還是參考一下API裡面的吧 實作list接口的主要有:ArrayList、LinkedList、Vector和Stack
ArrayList
通過名字就能知道這是個啥了吧,灰常類似于數組
ArrayList實作了可變大小的數組。它允許所有元素,包括null。ArrayList沒有同步,僅有Vector實作了同步(線程安全),每個ArrayList執行個體都有一個容量(Capacity),即用于存儲元素的數組的大小,預設值好像是10。這個容量可随着不斷添加新元素而自動增加,但是增長算法并沒有定義。當需要插入大量元素時,在插入前可以調用ensureCapacity方法(設定長度最小值)來增加ArrayList的容量以提高插入效率。和LinkedList一樣,ArrayList也是非同步的(unsynchronized)
案例:
package test;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Test {
public static int flg = 0;
public int self = 0;
public Test() {
++flg;
self = flg;
System.out.println("已經初始化了:" + flg + "個執行個體");
}
public static void main(String[] args) {
// TODO Auto-generated method stub
/*
* 加入範式Test表示這裡存儲Test類型,并且可以獲得具體值之後,可以通路對象的方法和屬性 比如下述:list.get(i).flg
* 若不添加範式,則無法通路該self屬性或者其他方法
*/
List<Test> list = new ArrayList<Test>();
for (int i = 0; i < 5; i++) {
list.add(new Test());
System.out.println(list.get(i).self);
}
list.add(new Test());
System.out.println(list.get(list.size() - 1).self);
list.addAll(list);
System.out.println(list.size());
list.add(0, null);
System.out.println(list.get(0));
// 使用疊代器去周遊,注意給疊代器添加一個泛型
Iterator<Test> myiterator = list.listIterator();
Test test;
while (myiterator.hasNext()) {
test = myiterator.next();
if (test != null)
System.out.println(test.self);
else
System.out.println(test);
}
}
}
LinkedList
LinkedList實作了List接口,允許null元素。此外LinkedList提供額外的get,remove,insert方法在 LinkedList的首部或尾部。這些操作使LinkedList可被用作堆棧(stack),隊列(queue)或雙向隊列(deque),該類實作了Deque接口,提供了add和poll方法實作FIFO先進先出的隊列操作,一起其他的堆棧和雙向隊列操作。
注意LinkedList沒有同步方法。如果多個線程同時通路一個List,則必須自己實作通路同步。一種解決方法是在建立List時構造一個同步的List:
List list = Collections.synchronizedList(new LinkedList(...));
案例:
基礎操作
<span style="font-size:14px;">package test;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
public class Test {
public static int flg = 0;
public int self = 0;
public Test() {
++flg;
self = flg;
System.out.println("已經初始化了:" + flg + "個執行個體");
}
public static void main(String[] args) {
// TODO Auto-generated method stub
/*
* 加入範式Test表示這裡存儲Test類型,并且可以獲得具體值之後,可以通路對象的方法和屬性 比如下述:list.get(i).flg
* 若不添加範式,則無法通路該self屬性或者其他方法
*/
List<Test> list = new LinkedList<Test>();
int i = 0;
Test test = new Test();
list.add(0, test);
while (i < 5) {
list.add(new Test());
i++;
}
System.out.println("indexOf :" + list.indexOf(test));
System.out.println("lastIndexOf :" + list.lastIndexOf(test));
System.out.println("contants :" + list.contains(test));
System.out.println("contants :" + list.contains(new Test()));
// 注意疊代器的使用,給疊代器指定正确的泛型,才可以通路詳細的屬性和方法
Iterator<Test> iterator = list.listIterator();
while (iterator.hasNext()) {
System.out.println(iterator.next().self);
}
}
}</span>
至于大家都說了LinkedList可以當做隊列或者堆棧,從表面上,LinkedList實作了Deque等接口,确實可以這麼去用了,但是我在實踐的過程中,我得到的LinkedList的執行個體,不知道怎麼情況,沒有api裡面給出的poll方法,是以我這裡沒有做關于這個的案例的,但是模拟還是很簡單的
Vector
Vector類似于ArrayList,但是确實同步的,也就是說他是線程安全的,換句話說就是如果Vector建立了一個疊代器,那麼這個疊代器正在使用的時候,另一個線程改變了這個Vector的狀态,那麼就會産生異常 用法接近ArrayList,參照上述以及API即可Stack
棧這個東西,在資料結構裡面學過的,以前很熟悉,可是現在我就陌生了,大概的知道這個有一個特性:LIFO後進先出,在java中Stack是基于Vector的,除了基本的方法push()和pop()方法,java的Stack還提供了一個peek()擷取棧頂元素值的方法,empty方法判斷是否為空,search方法尋找某個元素在棧中的位置等 既然實作了List接口,那麼就會有list的一些操作方法 簡單案例:
package test;
import java.util.Stack;
public class Test {
public static int flg = 0;
public int self = 0;
public Test() {
++flg;
self = flg;
System.out.println("已經初始化了:" + flg + "個執行個體");
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Stack stack = new Stack();
for (int i = 0; i < 5; i++)
stack.push(i);
System.out.println(stack.peek());
System.out.println(stack.size());
int len = stack.size();
for (int i = 0; i < len; i++)
System.out.println(stack.pop());
System.out.println(stack.size());
}
}
Set
Set是一種不可重複的Collection接口,set的檢索效率相對較低,而與list對比,插入和删除的效率較高,不會引起其他元素位置的變化,Set是無序的,Set和List最大的差別是Set不允許重複
我們重點要記住這家夥不能重複
Set不允許重複的原因是,他是基于Map實作的,而Map中的key是不允許重複的,Set中使用的僅僅是Map中的key
Set常見的方法,詳細情況請參考Java語言的API
add(E e) :如果 set 中尚未存在指定的元素,則添加此元素
addAll(Collection<? extendsE> c) :如果 set 中沒有指定 collection 中的所有元素,則将其添加到此 set 中
clear() :移除此 set 中的所有元素
contains(Object o) : 如果 set 包含指定的元素,則傳回true
containsAll(Collection<?> c) :如果此 set 包含指定 collection 的所有元素,則傳回true
equals(Object o) :比較指定對象與此 set 的相等性
isEmpty() :如果 set 不包含元素,則傳回true
iterator() :傳回在此 set 中的元素上進行疊代的疊代器
remove(Object o) : 如果 set 中存在指定的元素,則将其移除
removeAll(Collection<?> c) :移除 set 中那些包含在指定 collection 中的元素
retainAll(Collection<?> c) : 僅保留 set 中那些包含在指定 collection 中的元素
size() :傳回 set 中的元素數
toArray() :傳回一個包含 set 中所有元素的數組
比較蛋疼,set中是沒有get方法擷取元素對象的,隻能通過疊代器來通路資料
我們常見的Set實作類有:TreeSet、HashSet和LinkedHashSet
TreeSet
TreeSet居然是有序的,預設是自然序列的,排序方式可以使用自帶的,也可以使用自定義,在建立TreeSet的時候,傳遞一個自定義的排序規則對象即可,另外既然它是有序的,有是基于TreeMap實作的,那麼TreeSet中的元素對象必須實作Comparable接口,但是如果是字元串對象的話,呵呵,不需要了,String本身就已經實作了Comparable接口了 很顯然,在測試過程中沒有發現get方法,看到了iterator方法,那麼也就意味着,隻能通過疊代器通路詳細資料了 簡單案例: 需要實作Comparable接口(String不需要,String已經實作了,不過你可以重新寫一個,用自己定義的)
package test;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
public class Test implements Comparable<Test> {
public static int flg = 0;
public int self = 0;
public Test() {
++flg;
self = flg;
System.out.println("已經初始化了:" + flg + "個執行個體");
}
@Override
public int compareTo(Test o) {
// TODO Auto-generated method stub
if (this.self < o.self)
return -1;
else if (this.self > o.self)
return 1;
else
return 0;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Set set = new TreeSet();
for (int i = 0; i < 5; i++)
set.add(new Test());
System.out.println(set.size());
Iterator<Test> it = set.iterator();
while (it.hasNext()) {
System.out.println(it.next().self);
}
}
}
HashSet
和TreeSet一樣隻能通過疊代器來通路資料,HashSet是基于HashMap實作的,但是是無序的,常用的方法和Set接口的相近,記住一點,通路必須通過疊代器,疊代的順序不能保證是和插入的順序一緻,這點與LinkedHashSet正好是相反的
案例:有待補充
LinkedHashSet
LinkedHashSet是一個連結清單結構,與上述一緻,通過疊代器周遊,但周遊的順序和插入的順序一緻
案例:有待補充
Map
(其實我接觸Map應該是從學習Hibernate課堂上,老師說過,學java的時候,老師講到基本循環結構就結束課程了,要命,呵呵)Map是一個頂層接口,主要是處理映射(key/value)類型,用于存儲鍵值對的Map接口提供了三種Collection視圖,允許以鍵集、值集或者鍵值對映射關系集的方式來通路某個映射的内容,疊代的順序定義為疊代器在collection視圖上傳回的元素順序,有些Map實作可以確定順序,比如TreeMap,但有些是不可以的,比如HashMap構造方法:構造方法一般有兩種:一種是無參數,另一種是帶一個Map類型的參數常用方法:put方法,添加鍵值對,這裡對于Map的介紹,還是以例子為主吧。實作Map接口的主要有TreeMap、HashMap等TreeMap
基于紅黑樹(Red-Black tree)的 NavigableMap 平衡二叉樹實作。該映射根據其鍵的自然順序進行排序,或者根據建立映射時提供的 Comparator 進行排序,具體取決于使用的構造方法。
構造函數: TreeMap() :使用鍵的自然順序構造一個新的、空的樹映射
TreeMap(Comparator<? super K> comparator) 構造一個新的、空的樹映射,該映射根據給定比較器進行排序
TreeMap(Map<? extends K,? extends V> m) 構造一個與給定映射具有相同映射關系的新的樹映射,該映射根據其鍵的自然順序 進行排序
TreeMap(SortedMap<K,? extends V> m) 構造一個與指定有序映射具有相同映射關系和相同排序順序的新的樹映射
常用方法 Map.Entry<K,V> ceilingEntry(K key)
傳回一個鍵-值映射關系實體,與大于等于給定鍵的最小鍵關聯;如果不存在這樣的鍵,則傳回 null
get(Object key) :傳回指定鍵所映射的值,如果對于該鍵而言,此映射不包含任何映射關系,則傳回 null
keySet() :傳回此映射包含的鍵的 Set 視圖
navigableKeySet() :傳回此映射中所包含鍵的 NavigableSet 視圖
values() :傳回此映射包含的值的 Collection 視圖
put(K key, V value) :将指定值與此映射中的指定鍵進行關聯
putAll(Map<? extends K,? extends V> map) :将指定映射中的所有映射關系複制到此映射中
remove(Object key) :如果此 TreeMap 中存在該鍵的映射關系,則将其删除
HashMap
基于哈希表的 Map 接口的實作。此實作提供所有可選的映射操作,并允許使用 null 值和 null 鍵。(除了非同步和允許使用 null 之外,HashMap 類與 Hashtable 大緻相同。)此類不保證映射的順序,特别是它不保證該順序恒久不變。
此實作假定哈希函數将元素适當地分布在各桶之間,可為基本操作(get 和 put)提供穩定的性能。疊代 collection 視圖所需的時間與 HashMap 執行個體的“容量”(桶的數量)及其大小(鍵-值映射關系數)成比例。是以,如果疊代性能很重要,則不要将初始容量設定得太高(或将加載因子設定得太低)
詳細資訊,還是API比較全,晚上看累了,不想寫了