集合:
在周遊Arraylist集合的時候,想要對性能上優化的話盡量使用for循環,少用foreach。因為對于for循環JVM隻是簡單地增加了一個整型變量,它直接從記憶體讀值。這使它非常快。但forEach疊代則不同,JVM必須把forEach轉換為疊代器并為每個資料項調用hashNext(),這就是為什麼for循環比foreach快的原因。
而在LinkedList中,周遊還是用foreach或者疊代器,也可以使用removeFist()或者removeLast(),但是它們在周遊的時候回删除原資料。
arraylist集合查詢快,添加删除慢
linkedlist添加删除快,查詢慢
使用ArrayList集合的時候如果知道添加的數量,設定集合長度性能更好,如果資料近百萬的話設定該資料的三分一長度,如果是十萬級别的,設定該資料數量的長度即可。
Collection接口的remove()方法和Iterator接口的remove()方法差別?
①性能方面:
Collection的remove方法必須首先找出要被删除的項,找到該項的位置采用的是單連結清單結構查詢,
單連結清單查詢效率比較低,需要從集合中一個一個周遊才能找到該對象;
Iterator的remove方法結合next()方法使用,比如集合中每隔一項删除一項,Iterator的remove()效率更高
②容錯方面:
在使用Iterator周遊時,如果使用Collection的remove則會報異常,
會出現ConcurrentModificationException,因為集合中對象的個數會改變而Iterator 内部對象的個數不會,
不一緻則會出現該異常,
在使用Iterator周遊時,不會報錯,因為iterator内部的對象個數和原來集合中對象的個數會保持一緻
Array與ArrayList有什麼差別?
①Array是Java中的數組,聲明數組有三種方式
int[] a=new int[10];
int a[]=new int[10];
int a[]={1,2,3,4};
②ArrayList是動态數組,也就是數組的複雜版本,它可以動态的添加和删除元素,被稱為”集合“,集合的聲明如下
ArrayList list = new ArrayList(10);
ArrayList<Integer> list1 = new ArrayList<Integer>();
可以看出:在不使用泛型的情況下,這個list是可以添加進不同類型的元素的,而且arraylist是可以不用指定長度的。在使用泛型時,我們就隻能添加一種類型的資料了
可以從三方面回答面試官
①.ArrayList是Array的複雜版本
②.存儲的資料類型:Array隻能存儲相同資料類型的資料,而ArrayList可以存儲不同資料類型的資料
③.長度的可變:Array的長度是固定的,而ArrayList的長度是可變的
怎樣将一個數組轉成List,有什麼方法?
String[]str={"111","222","333"};
List<String> strings=Arrays.asList(str);
數組轉成list之後不能進行add和remove的
如果需要的話,則:
List<String>newStrings=new ArrayList<String>(strings);
List轉數組的方法:
List<String>str=new ArrayList<String>();
str.add("111");
str.add("222");
str.add("333");
String[] newString=str.toArray(new String[str.size]);
HashSet、TreeSet、LinkedHashSet差別?
當需要速度快的集合時使用HashSet.
需要集合有序的排序的時候使用TreeSet.
需要根據插入的順序排序的時候使用LinkedHashSet.
HashMap、TreeMap、linkedHashMap差別?
在Map中插入,删除和定位元素,HashMap是最好的選擇
需要有序的集合時使用TreeMap
需要按照插入順序排序時使用linkedHashMap
HashMap和HashSet差別?
HashMap 實作了Map接口 存儲鍵值對 調用put()向map中添加元素 HashMap使用key計算hashcode HashMap相對于HashSet較快,因為它是使用唯一的鍵擷取對象
HashSet 實作了Set接口 存儲對象 調用add()向set中添加元素 HashSet使用成員對象計算hashcode HashSet較HashMap來說比較慢
HashMap的實作原理?
通過put和get存儲和擷取對象,存儲對象時,我們将K/V傳給put方法時,它調用hashcode計算hash進而得到bucket位置,進一步存儲,HashMap會根據目前bucket的占用情況自動調整容量。擷取對象時,我們将K傳遞給get,他調用hashcode計算hash進而得到bucket位置,并進一步調用equals()方法确認鍵值對。
HashMap的幾個重要的資訊:
預設大小為16( 2 的4次方)
擴容機制:當目前數超過總數的75%時擴充,擴充為原來的2倍,也就是2的n+1次方。
最大存2的30次方
List、Set、Map之間的差別?
List和Set都繼承Collection,但是Map不是Collection的子接口。
List 可以允許重複的元素 可以插入多個null元素 有序的容器,插入的順序和輸出的順序一樣
Set 不允許重複元素 隻允許一個null元素 無序容器
Map 鍵值對存儲,鍵必須唯一,但是值可以重複 鍵隻允許一個null,值可以允許有多個null
無序容器
Map集合知識:
- 關于HashMap的一些說法:
- a) HashMap實際上是一個“連結清單散列”的資料結構,即數組和連結清單的結合體。HashMap的底層結構是一個數組,數組中的每一項是一條連結清單。
- b) HashMap的執行個體有倆個參數影響其性能: “初始容量” 和 裝填因子。
- c) HashMap實作不同步,線程不安全。 HashTable線程安全
- d) HashMap中的key-value都是存儲在Entry中的。
- e) HashMap可以存null鍵和null值,不保證元素的順序恒久不變,它的底層使用的是數組和連結清單,通過hashCode()方法和equals方法保證鍵的唯一性
- f) 解決沖突主要有三種方法:定址法,拉鍊法,再散列法。HashMap是采用拉鍊法解決哈希沖突的。 注: 連結清單法是将相同hash值的對象組成一個連結清單放在hash值對應的槽位; 用開放定址法解決沖突的做法是:當沖突發生時,使用某種探查(亦稱探測)技術在散清單中形成一個探查(測)序列。 沿此序列逐個單元地查找,直到找到給定 的關鍵字,或者碰到一個開放的位址(即該位址單元為空)為止(若要插入,在探查到開放的位址,則可将待插入的新結點存人該位址單元)。 拉鍊法解決沖突的做法是: 将所有關鍵字為同義詞的結點連結在同一個單連結清單中 。若標明的散清單長度為m,則可将散清單定義為一個由m個頭指針組成的指針數 組T[0..m-1]。凡是散列位址為i的結點,均插入到以T[i]為頭指針的單連結清單中。T中各分量的初值均應為空指針。在拉鍊法中,裝填因子α可以大于1,但一般均取α≤1。拉鍊法适合未規定元素的大小。
- 2. Hashtable和HashMap的差別: a) 繼承不同。 public class Hashtable extends Dictionary implements Map
public class HashMap extends AbstractMap implements Map
b) Hashtable中的方法是同步的,而HashMap中的方法在預設情況下是非同步的。在多線程并發的環境下,可以直接使用Hashtable,但是要使用HashMap的話就要自己增加同步處理了。
c) Hashtable 中, key 和 value 都不允許出現 null 值。 在 HashMap 中, null 可以作為鍵,這樣的鍵隻有一個;可以有一個或多個鍵所對應的值為 null 。當 get() 方法傳回 null 值時,即可以表示 HashMap 中沒有該鍵,也可以表示該鍵所對應的值為 null 。是以,在 HashMap 中不能由 get() 方法來判斷 HashMap 中是否存在某個鍵, 而應該用 containsKey() 方法來判斷。
d) 兩個周遊方式的内部實作上不同。Hashtable、HashMap都使用了Iterator。而由于曆史原因,Hashtable還使用了Enumeration的方式 。
e) 哈希值的使用不同,HashTable直接使用對象的hashCode。而HashMap重新計算hash值。
f) Hashtable和HashMap它們兩個内部實作方式的數組的初始大小和擴容的方式。HashTable中hash數組預設大小是11,增加的方式是old*2+1。HashMap中hash數組的預設大小是16,而且一定是2的指數。 注: HashSet子類依靠hashCode()和equal()方法來區分重複元素。 HashSet内部使用Map儲存資料,即将HashSet的資料作為Map的key值儲存,這也是HashSet中元素不能重複的原因。而Map中儲存key值的,會去判斷目前Map中是否含有該Key對象,内部是先通過key的hashCode,确定有相同的hashCode之後,再通過equals方法判斷是否相同。