更新時間:2020-07-06 15:50:51 來源:動力節點 瀏覽2466次
1、ArrayList和LinkedList的區別?
是否保證線程安全:ArrayList和LinkedList都是不同步的,也就是不保證線程安全;
底層數據結構:Arraylist底層使用的是Object數組;LinkedList底層使用的是雙向循環鏈表數據結構;
插入和刪除是否受元素位置的影響:①ArrayList采用數組存儲,所以插入和刪除元素的時間復雜度受元素位置的影響。比如:執行add(E e)方法的時候,ArrayList會默認在將指定的元素追加到此列表的末尾,這種情況時間復雜度就是O(1)。但是如果要在指定位置i插入和刪除元素的話(add(int index,E element))時間復雜度就為O(n-i)。因為在進行上述操作的時候集合中第i和第i個元素之后的(n-i)個元素都要執行向后位/向前移一位的操作。②LinkedList采用鏈表存儲,所以插入,刪除元素時間復雜度不受元素位置的影響,都是近似O(1)而數組為近似O(n)。
是否支持快速隨機訪問:LinkedList不支持高效的隨機元素訪問,而ArrayList實現了RandmoAccess接口,所以有隨機訪問功能??焖匐S機訪問就是通過元素的序號快速獲取元素對象(對應于get(int index)方法)。
內存空間占用:ArrayList的空間浪費主要體現在在list列表的結尾會預留一定的容量空間,而LinkedList的空間花費則體現在它的每一個元素都需要消耗比ArrayList更多的空間(因為要存放直接后繼和直接前驅以及數據)。
補充:ArrayList的增刪未必就是比LinkedList要慢:
如果增刪都是在末尾來操作【每次調用的都是remove()和add()】,此時ArrayList就不需要移動和復制數組來進行操作了。如果數據量有百萬級的時,速度是會比LinkedList要快的。
如果刪除操作的位置是在中間。由于LinkedList的消耗主要是在遍歷上,ArrayList的消耗主要是在移動和復制上(底層調用的是arrayCopy()方法,是native方法)。LinkedList的遍歷速度是要慢于ArrayList的復制移動速度的如果數據量有百萬級的時,還是ArrayList要快。
2、ArrayList實現RandomAccess接口有何作用?為何LinkedList卻沒實現這個接口?
RandomAccess接口只是一個標志接口,只要List集合實現這個接口,就能支持快速隨機訪問。實現RandomAccess接口的List集合采用一般的for循環遍歷,而未實現這接口則采用迭代器,即ArrayList一般采用for循環遍歷,而LinkedList一般采用迭代器遍歷;
ArrayList用for循環遍歷比iterator迭代器遍歷快,LinkedList用iterator迭代器遍歷比for循環遍歷快。所以說,當我們在做項目時,應該考慮到List集合的不同子類采用不同的遍歷方式,能夠提高性能。
Java集合類中元素的訪問分為隨機訪問和順序訪問。隨機訪問一般是通過index下標訪問,行為類似數組的訪問。而順序訪問類似于鏈表的訪問,通常為迭代器遍歷。
以List接口及其實例為例。ArrayList是典型的隨機訪問型,而LinkedList則是順序訪問型。List接口既定義了下標訪問方法又定義了迭代器方法。所以其實例既可使用下標隨機訪問也可以使用迭代器進行遍歷。但這兩種方式的性能差異很明顯。
RandomAccess接口
JDK中的RandomAccess接口是一個標記接口,它并未定義方法。其目的是用于指示實現類具有隨機訪問特性,在遍歷時使用下標訪問較迭代器更快。
3.ArrayList的擴容機制?
當使用add方法的時候首先調用ensureCapacityInternal方法,傳入size+1進去,檢查是否需要擴充elementData數組的大小;
newCapacity=擴充數組為原來的1.5倍(不能自定義),如果還不夠,就使用它指定要擴充的大小minCapacity,然后判斷minCapacity是否大于MAX_ARRAY_SIZE(Integer.MAX_VALUE-8),如果大于,就取Integer.MAX_VALUE;
擴容的主要方法:grow;
ArrayList中copy數組的核心就是System.arraycopy方法,將original數組的所有數據復制到copy數組中,這是一個本地方法。
5.Array和ArrayList有何區別?什么時候更適合用Array?
Array可以容納基本類型和對象,而ArrayList只能容納對象;
Array是指定大小的,而ArrayList大小是固定的。
什么時候更適合使用Array:
4.如果列表的大小已經指定,大部分情況下是存儲和遍歷它們;
對于遍歷基本數據類型,盡管Collections使用自動裝箱來減輕編碼任務,在指定大小的基本類型的列表上工作也會變得很慢;
如果你要使用多維數組,使用[][]比List>更容易。
5.什么是Iterator?
一些集合類提供了內容遍歷的功能,通過java.util.Iterator接口。這些接口允許遍歷對象的集合。依次操作每個元素對象。當使用Iterators時,在獲得Iterator的時候包含一個集合快照。通常在遍歷一個Iterator的時候不建議修改集合本省。
6.Iterator與ListIterator有什么區別?
Iterator:只能正向遍歷集合,適用于獲取移除元素。ListIerator:繼承Iterator,可以雙向列表的遍歷,同樣支持元素的修改。
Iterator可以遍歷Set和List集合,而ListIterator只能遍歷List
ListIterator從Iterator接口繼承,然后添加了一些額外的功能,比如添加一個元素、替換一個元素、獲取前面或后面元素的索引位置。
7.什么叫做快速失敗特性?
從高級別層次來說快速失敗是一個系統或軟件對于其故障做出的響應。一個快速失敗系統設計用來即時報告可能會導致失敗的任何故障情況,它通常用來停止正常的操作而不是嘗試繼續做可能有缺陷的工作。當有問題發生時,快速失敗系統即時可見地發錯錯誤告警。在Java中,快速失敗與iterators有關。如果一個iterator在集合對象上創建了,其它線程欲“結構化”的修改該集合對象,并發修改異常(ConcurrentModificationException)拋出。
8.為什么Vector類認為是廢棄的或者是非官方地不推薦使用?或者說為什么我們應該一直使用ArrayList而不是Vector?
默認情況下你是非同步訪問的,Vector同步了每個方法,你幾乎從不要那樣做,通常有想要同步的是整個操作序列。同步單個的操作也不安全(如果你迭代一個Vector,你還是要加鎖,以避免其它線程在同一時刻改變集合).而且效率更慢。當然同樣有鎖的開銷即使你不需要,這是個很糟糕的方法在默認情況下同步訪問。你可以一直使用Collections.sychronizedList來裝飾一個集合。
事實上Vector結合了“可變數組”的集合和同步每個操作的實現。這是另外一個設計上的缺陷。Vector還有些遺留的方法在枚舉和元素獲取的方法,這些方法不同于List接口,如果這些方法在代碼中程序員更趨向于想用它。盡管枚舉速度更快,但是他們不能檢查如果集合在迭代的時候修改了,這樣將導致問題。盡管以上諸多原因,Oracle也從沒宣稱過要廢棄Vector。
9.哪些集合類提供對元素的隨機訪問?
ArrayList、HashMap、TreeMap和HashTable類提供對元素的隨機訪問。
10.哪些集合類是線程安全的?
Vector、HashTable、Properties和Stack是同步類,所以它們是線程安全的,可以在多線程環境下使用。
以上就是動力節點java培訓機構的小編針對“2020年Java集合類面試題及答案”的內容進行的回答,希望對大家有所幫助,如有疑問,請在線咨詢,有專業老師隨時為你服務。
0基礎 0學費 15天面授
有基礎 直達就業
業余時間 高薪轉行
工作1~3年,加薪神器
工作3~5年,晉升架構
提交申請后,顧問老師會電話與您溝通安排學習