首先,出現今天的需求主要是打算把數據結構,java集合,真實場景的處理都好好的再過一遍。我寫了一個實現約瑟夫環的算法,想着在arraylist和linkedlist之間做選擇,對比。很多時候功能做出來後,很少是能再去修改,情願做一個新的。現在想想這個習慣應該改一下。
從整體上來看下集合家族。
玩java的時候,先接觸的是數組,那麼對於集合的理解也是相對於數組的,所以說下區別:
1.數組是大小固定的,並且在同一個數組只能存放類型一樣的數據(基礎類型/引用類型)。
2.java集合可以存儲和操作數目不固定的一組數據,所有的java集合都在java.util包中,集合只能存放引用類型的數據,不能存放基礎數據類型。java集合分3個類型:set(集)、list(列表)、map(映射)。他們3個都是接口。
可以看到Collection是集合類的上級接口,繼承它的接口主要有set和list。而很容易混淆的是Collections,它是針對集合類的一個工具類,它提供了一系列靜態方法實現對各種集合的搜索,排序,線程安全化等操作。
同樣的,Array類提供了動態創建和訪問java數組的方法。Arrays類是數組的工具類,提供了1.給數組賦值2.對數組排序3.比較數組4.查找數組元素,這些操作方法。
圖的右側,還有comparable和comparator已經寫過了就不多少了。
這個圖上錯綜的分支樹,熟悉的要很熟悉,不熟悉的知道怎麼回事。說不定冷知識那天剛好要用到。
Arraylist和linkedlist寫過了,這裏不寫。從java認證的題目來一下。
幾個面試常見問題:
1.ArrayList和Vector有什麼區別?HashMap和HashTable有什麼區別?
A:Vector和HashTable是線程同步的(synchronized)。性能上,ArrayList和HashMap分別比Vector和Hashtable要好。
2.大致講解java集合的體系結構:
A:List、Set、Map是這個集合體系中最主要的三個接口。
其中List和Set繼承自Collection接口。
Set不允許元素重複。HashSet和TreeSet是兩個主要的實現類。
List有序且允許元素重複。ArrayList、LinkedList和Vector是三個主要的實現類。
Map也屬於集合系統,但和Collection接口不同。Map是key對value的映射集合,其中key列就是一個集合。key不能重複,但是value可以重複。HashM ap、TreeMap和Hashtable是三個主要的實現類。
SortedSet和SortedMap接口對元素按指定規則排序,SortedMap是對key列進行排序。
3.集合中鍵值是否允許null小結
- List:可以有多個null,可以有重複值。
- HashSet:能插入一個null(因爲內部是以 HashMap實現 ),忽略不插入重複元素。
- TreeSet:不能插入null (因爲內部是以 TreeMap 實現 ) ,元素不能重複,如果待插入的元素存在,則忽略不插入,對元素進行排序。
- HashMap:允許一個null鍵與多個null值,若重複鍵,則覆蓋以前值。
- TreeMap:不允許null鍵(實際上可以插入一個null鍵,如果這個Map裏只有一個元素是不會報錯的,因爲一個元素時沒有進行排序操作,也就不會報空指針異常,但如果插入第二個時就會立即報錯),但允許多個null值,覆蓋已有鍵值。
- HashTable:不允許null鍵與null值(否則運行進報空指針異常)。也會覆蓋以重複值。基於線程同步。
4.對List的選擇:
- 對於隨機查詢與迭代遍歷操作,數組比所有的容器都要快。
- 從中間的位置插入和刪除元素,LinkedList要比ArrayList快,特別是刪除操作。
- Vector通常不如ArrayList快,則且應該避免使用,它目前仍然存在於類庫中的原因是爲了支持過去的代碼。
- 最佳實踐:將ArrayList作爲默認首選,只有當程序的性能因爲經常從list中間進行插入和刪除而變差的時候,纔去選擇LinkedList。當然了,如果只是使用固定數量的元素,就應該選擇數組了。
5.對Set的選擇:
- HashSet的性能總比TreeSet好(特別是最常用的添加和查找元素操作)。
- TreeSet存在的唯一原因是,它可以維持元素的排序狀態,所以只有當你需要一個排好序的Set時,才應該使用TreeSet。
- 對於插入操作,LinkedHashSet比HashSet略微慢一點:這是由於維護鏈表所帶來額外開銷造成的。不過,因爲有了鏈表,遍歷LinkedHashSet會比HashSet更快。
6.對Map的選擇:
- Hashtable和HashMap的效率大致相同(通常HashMap更快一點,所以HashMap有意取代Hashtable)。
- TreeMap通常比HashMap慢,因爲要維護排序。
- HashMap正是爲快速查詢而設計的。
- LinkedHashMap比HashMap慢一點,因爲它維護散列數據結構的同時還要維護鏈表。
7.Stack基於線程安全,Stack類是用Vector來實現的(public class Stack extends Vector),但最好不要用集合API裏的這個實現棧,因爲它繼承於Vector,本 就是一個錯誤的設計,應該是一個組合的設計關係。
8.Iterator對ArrayList(LinkedList)的操作限制:
- 剛實例化的迭代器如果還沒有進行後移(next)操作是不能馬上進行刪除與修改操作的。
- 可以用ListIterator對集合連續添加與修改,但不能連續刪除。
- 進行添加操作後是不能立即進行刪除與修改操作的。
- 進行刪除操作後可以進行添加,但不能進行修改操作。
- 進行修改後是可以立即進行刪除與添加操作的。
/**
* 集合的大小會變化,變成後面剩下一個人。
*
* @param N
* 人數
* @param M
* 報數
* @param list
*/
public void playGame(int N, int M, ArrayList<Integer> list) {
int k = 0;
while (list.size() > 0) {
k = k + M;
// 第m人的索引位置
k = k % (list.size()) - 1;
// 判斷是否到隊尾
if (k < 0) {
System.out.println(list.get(list.size() - 1));
list.remove(list.size() - 1);
k = 0;
} else {
System.out.println(list.get(k));
list.remove(k);
}
pointList(list);
}
}
/**
* 打印集合
*
* @param list
*/
public void pointList(ArrayList<Integer> list) {
for (Integer integer : list) {
System.out.print("<" + integer + ">");
}
}