1,集合框架是java提供的方便用戶存儲數據工具,通過使用集合框架,開發者可以省去大量的時間在基礎的數據結構設計上,從而提高開發效率
2,集合框架分爲Collection 和 Map,其中Collection包括Set,List,Queue。並且所以的Collection類都可以通過Iterator進行迭代。Map保存的是key-value,在Map中key是不能重複的,value是可重複的。所以利用代碼的重用性,Map將所有的value置爲空就是Set, key不能重用,但value可以重複,這就是List。Map實現的子類有HashMap
3,Set詳解
Set中不能包含相同元素,在此處的相同元素通過equals()方法判斷。所以在元素重寫equals()方法時,開發者需要特別的小心。
3.1 HashSet是Set的實現類,HashSet判斷元素的相等是通過equals()和hashCode()判斷,既equals()相等且hashCode()相等,則元素相等。當元素相等時,HashSet將拒絕加入該元素。在HashSet中元素的排列順序是根據hashCode()返回值決定的。如
class A {
@Override
public boolean equals(Object obj) {
return true;
}
}
class B {
@Override
public int hashCode() {
return 100;
}
}
class C{
@Override
public int hashCode() {
return 2000;
}
@Override
public boolean equals(Object obj) {
return true;
}
}
public static void main(String[] args) {
A a1=new A();
A a2=new A();
B b1=new B();
B b2=new B();
C c1=new C();
C c2=new C();
HashSet books=new HashSet<>();
books.add(a1);
books.add(a2);
books.add(b1);
books.add(b2);
books.add(c1);
books.add(c2);
System.out.println(books);
}
在main方法中,books集合增加了多個元素,其中A重載了equals()方法,因爲HashSet判斷兩個元素相等是通過equals()和hashCode()判斷,所以,一個equals()返回true不會導致下一個元素不能加入。從而,兩個A都被加入books。同理B只重載了hashCode()方法而沒有重載equals()方法,所以兩個B 都加入進來了。而C類因爲重載了兩個方法,並且返回值固定,equals()返回true,hashCode()返回2000,所以HashSet認爲這兩個C相同,只能加入一個C,最後結果是
[com.collection.A@7852e922, com.collection.C@7d0, com.collection.B@64, com.collection.B@64, com.collection.A@4e25154f]
3.2 LinkedHashSet繼承自HashSet,同樣,LinkedHashSet判斷兩個元素相等需要equals()和hashCode()兩個方法,但是元素排序時是根據插入順序決定的,先插入的在前,後插入的在後。如
LinkedHashSet notes=new LinkedHashSet<>();
notes.add(a1);
notes.add(a2);
notes.add(b1);
notes.add(b2);
notes.add(c1);
notes.add(c2);
System.out.println(notes);
同HashSet一樣,notes將加入兩個A,兩個B,一個C,它加入的順序如下
[com.collection.A@7852e922, com.collection.A@4e25154f, com.collection.B@64, com.collection.B@64, com.collection.C@7d0]
對比HashSet,a2插入在第二個。由此可見,LinkedHashSet的順序就是插入順序。
3.3 TreeSet 繼承Set,在TreeSet中的所有元素都將被排好序,從大到小升序排列,是一棵紅黑樹。如
TreeSet trees=new TreeSet<>();
trees.add(2);
trees.add(6);
trees.add(1);
trees.add(4);
trees.add(4);
trees.add(10);
System.out.println(trees);
將輸出
[1, 2, 4, 6, 10]
其中重複的4被忽略。在TreeSet中有幾實用方法,first()返回第一個元素,last()返回最後一個元素,headSet(5)返回小於5的元素且不包括5,tailSet(5) 返回大於5的元素幷包括5,subSet(1,3)返回[1,3)的元素。
3.4 EnumSet直接繼承Set,但是無法直接new出來,他的初始化方法包括以下幾個
enum e{
a,b,c,d
}
EnumSet seasons=EnumSet.allOf(e.class);
System.out.println(seasons);
seasons=EnumSet.noneOf(e.class);
seasons.add(e.b);
seasons.add(e.c);
System.out.println(seasons);
seasons=EnumSet.of(e.a,e.a);
System.out.println(seasons);
4. List詳解
在List中,允許重複元素,在元素插入的過程中,List會給每個插入的元素設置索引,通過該索引List可以很快的找到該元素
4.1 ArrayList 繼承List,他通過動態的分配內存而增加元素。如下
ArrayList books=new ArrayList<>();
books.add("b1");
books.add("b2");
books.add("b3");
books.add("b4");
books.add("b5");
books.add("b6");
books.add("b7");
System.out.println(books);
最終的結果是
[b1, b2, b3, b4, b5, b6, b7]
該打印順序與插入順序一致。同時ArrayList提供了一些可用的方法,如
books.add(1,"insert before b2");
System.out.println(books);
// [b1, insert before b2, b2, b3, b4, b5, b6, b7]
books.remove(2);
System.out.println(books);
// [b1, insert before b2, b3, b4, b5, b6, b7]
books.set(4, "replace b5");
System.out.println(books);
// [b1, insert before b2, b3, b4, replace b5, b6, b7]
System.out.println(books.subList(0, 4));
// [b1, insert before b2, b3, b4]
4.2 Stack繼承Vector,而Vector繼承List,在Stack中,元素遵循後進先出的原則,具體如下
Stack stack=new Stack<>();
stack.push("s1");
stack.push("s2");
stack.push("s3");
stack.push("s4");
System.out.println(stack);
// [s1, s2, s3, s4]
System.out.println(stack.peek());
// s4
System.out.println(stack);
// [s1, s2, s3, s4]
System.out.println(stack.pop());
// s4
System.out.println(stack);
//[s1, s2, s3]
peek()方法返回棧頂元素,但並不彈出。而pop()方法返回並彈出棧頂元素。
4.3 LinkedList是繼承List,是一個雙向的隊列。初始化如下;
LinkedList dequeue = new LinkedList<>();
dequeue.offer("d1");
dequeue.push("d2");
dequeue.offerFirst("d0");
dequeue.offerLast("d3");
System.out.println(dequeue);
輸出
[d0, d2, d1, d3]
在目前的研究中發現,offerFirst()和push()實現同樣功能,offerLast()和offer()實現相同功能。
5 Queue詳解
隊列是一種先進先出的數據結構,不允許隨機訪問元素
5.1 PriorityQueue繼承Queue。具體使用如下
PriorityQueue queue=new PriorityQueue<>();
queue.add("q1");
queue.add("q2");
queue.add("q3");
queue.add("q4");
queue.add("q5");
System.out.println(queue);
// [q1, q2, q3, q4, q5]
System.out.println(queue.poll());
//q1
System.out.println(queue);
//[q2, q4, q3, q5]
poll()方法將隊首元素出隊列,並且在隊列中刪除該元素。
5.2 ArrayQueue基於數組的隊列,所以隨機訪問快,具體如下
ArrayDeque stack=new ArrayDeque<>();
stack.push(1);
stack.push(2);
stack.push(4);
stack.push(3);
System.out.println(stack);
// [3, 4, 2, 1]
System.out.println(stack.peek());
//3
System.out.println(stack);
//[3, 4, 2, 1]
System.out.println(stack.pop());
//3
System.out.println(stack);
//[4, 2, 1]
6 迭代Collection
每一種Collection的實現類都有iterator()方法,通過該方法可以迭代該集合,如;
ArrayList a=new ArrayList<>();
a.add(1);
a.add(2);
Iterator iterator= a.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
最終輸出1,2
7 Map實現的子類
7.1 HashMap 和HashTable,這兩個子類通過equals()和hashCode()方法一起判斷元素是否相等。
class MapA {
int count;
public MapA(int count) {
this.count = count;
}
@Override
public int hashCode() {
// TODO Auto-generated method stub
return count;
}
@Override
public boolean equals(Object obj) {
// TODO Auto-generated method stub
return true;
}
}
class MapB{
@Override
public boolean equals(Object obj) {
// TODO Auto-generated method stub
return true;
}
}
main方法如下;
MapA a = new MapA(100);
MapA a2 = new MapA(100);
HashMap map = new HashMap<>();
map.put(a, "1");
map.put(a2, "2");
System.out.println(map);
MapB b=new MapB();
MapB b2=new MapB();
Hashtable taHashtable=new Hashtable<>();
taHashtable.put(b, "1");
taHashtable.put(b2, "2");
System.out.println(taHashtable);
輸出
{com.collection.MapA@64=2}
{com.collection.MapB@4e25154f=2, com.collection.MapB@7852e922=1}
此處原理和HashSet一樣。
7.2 LinkedHashMap是Map的鏈式存儲方式。能夠快速的增加和刪除元素。
LinkedHashMap linkedHashMap=new LinkedHashMap<>();
linkedHashMap.put("a", 100);
linkedHashMap.put("b", 89);
for(Object key:linkedHashMap.keySet()) {
System.out.println(key+"-->"+linkedHashMap.get(key));
}
輸出如下
a-->100
b-->89
7.3 Properties,該對象可以用來讀寫配置文件,如
Properties properties=new Properties();
properties.setProperty("username", "wudi");
properties.setProperty("password", "123456");
System.out.println(properties);
try {
properties.store(new FileOutputStream("test.txt"), "suit yourself");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
控制檯輸出
{password=123456, username=wudi}
刷新工程項目後,在src下會多一個test.txt文件。如下圖
其中test.txt文件如下
一般我們看見的xml文件,也可以直接使用Properties進行讀寫