集合與數組?
數組:(可以存儲基本數據類型)是用來存儲對象的一種容器,但是數組的長度固定,不適合在對象數量未知的情況下使用
集合:(只能存儲對象,對象類型可以不一樣)集合的長度可變,可在多數情況下使用
Collection接口是集合類的根接口,Java中沒有提供這個接口的直接的實現類,但是卻讓其被繼承產生了兩個接口
Set:不包含重復的元素
List:有序的集合,可以包含重復的元素,提供了按索引訪問的方式
Map是Java.util包中的另一個接口,它和Collection接口沒有關系,是相互獨立的,但是都屬於集合的一部分,Map包含了Key – Value對,Map不能包含重復的Key,但是可以包含相同的Value。
Iterator,所有的集合類都實現了Iterator接口,這是一個用於遍歷集合中元素的接口,主要包含以下三種方法:
- hasnext():是否還有下一個元素
- next():返回下一個元素
- remove():刪除當前元素
幾種重要的接口和類簡介
- List(有序,可重復)
List里存放的對象是有序的,同時也是可以重復的,List關注的是索引,擁有一系列和索引相關的方法,查詢速度快,因為往List集合里插入或刪除數據時,會伴隨着后面數據的移動,所以插入數據速度很慢
- Set(無序,不能重復)
Set里存放的對象是無序的,不能重復的,集合中的對象不按特定的方式排序,只是簡單的把對象放入集合中。
- Map(鍵值對,鍵唯一,值不唯一)
Map集合中存儲的時鍵值對,鍵不能重復,值可以重復,根據鍵得到值,對map集合遍歷時先得到鍵的Set集合,對Set集合遍歷,得到相對應的值。
遍歷
在集合中提供了以下四種的常見的輸出方式
- Iterator:迭代輸出,是使用最多的輸出方式
- ListIterator:是Iterator的子接口,用於專門輸出List中的內容‘
- Foreach輸出:JDK1.5之后提出的新功能。可以輸出數組或集合
- For循環
ArrayList和LinkedList
ArrayList和LinkedList在用法上沒有區別,但是在功能上還是有區別的
LinkedList經常用在增刪操作較多而查詢操作很少的情況
Arraylist經常用在查詢較多,增刪操作較少的情況下。
Map集合
實現類:HashMap,HashTable,LinkedHashMap和TreeMap
HashMap
HashMap是最常用的Map它根據鍵的HashCode來存儲元素,根據鍵可以直接獲取它的值,具有很快的訪問速度。
遍歷時,取得數據的順序是完全隨機的,因為鍵對象不可以重復,所以HashMap最多只允許一條記錄的鍵為Null,允許多條記錄的值為Null,是非同步的
HashTable
HashTable與HashMap類似,是HashMap的線程安全版,它支持線程的同步,任一時刻只有一個線程能寫HashTable
因此也導致了HashTable在寫入時會比較慢,它集成子Dictionary類,不同的時它不允許記錄的鍵或值為null,同時效率較低
LinkedHashMap
LinkedHashMap保存來記錄的插入順序,在用Iteraor遍歷LinkedHashMap時,先得到的記錄肯定是先插入的,在遍歷的時候會比HashMap慢,有HashMap的全部特性
TreeMap
TreeMap實現SortMap接口,能夠把它保存的記錄根據鍵順序,默認是按鍵值的升序排序(自然順序),可以指定排序的比較器,當用Iterator遍歷ThreeMap時,得到的記錄是排過序的,不允許Key值為空,非同步
Map的遍歷
- KeySet();
將Map中所有的鍵存入到set集合中因為set幾倍迭代器,所以可以迭代取出所有的鍵,再根據get方法獲取每一個鍵對應的值,KeySet()迭代后只能通過get()取Key。
- ebtrySet()
Set<Map.Entry<K,V>>entrySet()返回此映射值中包含的映射關系的Set視圖(一個關系就是一個兼職對)就是把(Key-value)作為一個整體一對一的存放到Set集合中,Map.Entry表示映射關系
EntrySet()迭代后可以e.getKey() ,e.getValue() 兩種方法來去Key和Value,返回的值是Entry接口
推薦使用entrySet()方法,效率較高
對於KeySet其實是遍歷了2次,一次轉為iterator,一次就是從HashMap中取出Key所對應的Value
Entryset()只是遍歷了第一次,它把Key和Value都放到了entry中,所以快了。兩種遍歷的遍歷時間相差還是很明顯的。
ArrayList和LinkedList的區別
- ArrayList是實現了基於動態數組的數據結構,LinkedList基於鏈表的數據結構
- 對於隨機訪問get和set,ArrayList性能優於LinkedList,因為LinkedList要移動指針
- 對於新增和刪除操作,add和remove,linkedList比較占優勢,因為ArrayList要移動數據,這一點要看實際情況的,若值對單條數據插入或刪除,ArrayList的速度反而要優於LinkedList,但是要是批量隨機的插入刪除數據,LinkedList的書讀大大優於ArrayList,因為ArrayList每插入一條數據,要移動插入點及之后的所有數據
HashMap與TreeMap
- HashMap通過hashcode對其內容進行快速查找,而TreeMap中所有的元素都保持着某種固定的順序,如果你需要得到一個有許多結果你就應該去使用TreeMap(HashMap中元素排列順序是不固定的)
- 在Map中插入,刪除和定位元素,HashMap是最好的選擇,但如果要按照自然順序或自定義順序遍歷鍵,那么TreeMap會更好,使用HashMap要求添加的鍵類明確定義了hashCode()和equals()的實現
連個Map中的元素一樣,但順序不一樣,導致hashCode()不一樣
同樣做測試:
在HashMap中,同樣的值的map。順序不同,equals時,false
在TreeMap中,同樣的值的map,順序不同,equals時,true,說明TreeMap在equals()時是整理了順序的。
HashTable與HashMap的區別
- 同步性:HashTable是線程安全的,也就是說是同步的,而HashMap是線程不安全的,不是同步的
- HashMap允許存在一個為null 的key,多個為null的元素
- HashTable的Key和Value都不允許為null
Java集合框架是什么,說出一些集合框架的優點
每種編程語言中都有集合,最初的Java版本中包含擊中集合類:Vector,Stack,HashTable和Array,隨着集合的廣泛使用,Java1.2提出囊括所有集合接口,實現和算法的集合框架,在保證線程安全的情況下,使用泛型和並發集合類,Java已經經歷了很久,它還包括在Java並發包中,阻塞接口以及他們的實現。集合框架的部分優點如下
- 使用核心集合類降低開發成本,而非實現我們自己的集合類
- 通過使用經過嚴格測試的結合框架,代碼質量會得到提高
- 通過使用JDK附帶的集合類,可以降低代碼維護成本
- 復用性和可操作性
集合框架中的泛型有什么優點
Java1.5中引入了泛型,所有的集合接口和實現都大量的使用它,泛型允許我們為集合提供一個可以容納的對象類型,因此,如果你想添加其他類型的任何元素,它都會在編譯時報錯,避免了再運行時出現錯誤,因此你將會在編譯時得到報錯信息,泛型也是的代碼整潔,我們不需要使用顯式轉換和instanceOf操作符。
Java集合框架的基礎接口有哪些
Collection為集合層級的根接口,一個集合代表一組對象,這些對象即為它的元素,Java不提供這個接口的任何直接實現。
Set是一個包含不重復元素的集合,這個接口對數字集合抽象進行建模,被用來代表集合,就如一副牌一樣。
List是一個有序集合,可以包含重復元素,你可以通過它的索引來訪問任何元素,List更像長度動態變換的數組
Map是一個將Key映射到Value的對象,一個Map不能包含重復的Key,每個Key最多只能映射一個Value
為何Map接口不繼承Collection接口
盡管Map接口和它的實現也是集合框架的一部分,但Map不是集合,集合也不是Map,因此Map繼承Collection毫無意義,反之亦然
Iterator是什么?
Iterator接口提供遍歷任何Collection的接口,我們可以從一個Collection中使用迭代器的方法來獲取迭代器實例,迭代器允許調用者在迭代過程中移出元素
HashMap是如何工作的
HashMap使用哈希算法,在put和get方法中,他是用hashCode()和equals()方法,當我們通過傳遞Key-value對,調用put方法的時候,HashMap使用key hashCode()和哈希算法,來找出存儲Key-value對的索引Entry存儲在LinkedList中,如果存在Entry,它使用equals()方法來檢查傳遞的Key是否已經存在如果存在,它會覆蓋Value,如果不存在,它會創建一個新的entry然后保存,讓我們通過傳遞key調用get()方法是,它再次使用hashCode()來找到數組中的索引,然后使用equals()方法找出正確的Entry,然后返回它的值。
HashCode()和equals()方法有和重要性
HashMap使用Key對象的HashCode()和equals()方法去決定Key-Value對的索引,當我們試着從HashMap中獲取值的時候,這些方法也會被用到,如果這些方法沒有正確的實現,這種情況下,兩個不同Key也會產生相同的HashCode()和equals()輸出
HashMap將會認為他們是相同的,然后覆蓋他們,而非把他們存儲到不同的地方,同樣的所有不允許存儲重復數據的集合類都使用HashCode()和equals()去查找重復,所以他們非常重要
Equals()和hashCode()的實現應該遵循以下規則:
- 如果o1.equals(o2),那么o1,hashCode()==o2.hashCode()總是為true 的
- 如果o1.hashCode()==02.hashCode(),並不意味着o1.equals(o2)會為true。
簡單來講:
HashCode相同,不一定對象相同
對象相同,HashCode一定相同。
能否使用任何類作為Map的Key
可以!
使用之前要考慮幾點
- 如果類重寫了equals()方法,它也應該重寫HashCode()方法
- 類的所有實例要遵循與equals()和HashCode()相關的規則
- 如果一個類沒有使用equals(),你不應該在HashCode()中使用它
HashMap和HashTable有何不同
- HashMap允許key和value為空,而HashTable不允許
- HashTable是同步的是安全的,而HashMap不是,所以HashMap適合單線程環境,HashTable適合多線程環境
如何決定選用HashMap還是ThreeMap
對於在Map中插入,刪除和定位元素這類的操作,HashMap是孔的選擇,然而,假如你需要對一個有序的Key集合進行遍歷,ThreeMap是更高的選擇,基於你的Collection的大小,也許想HashMap中添加元素會更快,將Map換位TheeMap進行有序Key的遍歷
ArrayList 和 Vertor有何異同
ArrayList和Vector在很多時候都很類似
- 兩者都是基於索引的,內部又一個數組支持
- 兩者維護插入的順序,我們可以根據插入順序來獲取元素
- ArrayList和Vector兩者允許null值,也可以使用索引值對元素進行隨機訪問
不同點
- Vector是同步的是安全的,而ArrayList不是
- ArrayList比Vector快
- ArrayList更加的通用
Array和ArrayList有何區別?什么時候更適合用Array?
- Array可以容納基本類型和對象,而ArrayList只能容納對象
- Array是指定大小的,而ArrayList大小是固定的
- Array沒有ArrayList那么多的功能,比如addAll,rumoveAll和Iterator等
- 如果列表的大小已經指定,大部分的情啊狂還是存儲和遍歷它們
- 如果要使用多維數組,使用Array[][]要比List<List<>>更容易
ArrayList和LinkedList有何區別?
ArrayList和Linked兩者都實現了List接口,但是它們之間有些不同
- ArrrayList是時間了基於動態數組的數據結構,ListedList是基於鏈表的數據結構
- 對於隨機訪問get()和set()ArrayList速度優於LinkedList,因為LinkedList要移動指針
- 對於新增和刪除操作add和remove,LinkedList比較占優勢,因為ArrayList要移動數據,
- 兩者都是現成不安全的,允許重復的。
哪些集合提供對元素的隨機訪問?
ArrayList,HashMap,TreeMap和HashTable都提供對元素的隨機訪問。