Java每天10道面試題,跟我走,offer有!(五) 原

 

41.Iterator、ListIterator 和 Enumeration的區別?

 
迭代器是一種設計模式, 它是一個對象, 它可以遍歷並選擇序列中的對象, 而開發人員不需要了解 該序列的底層結構。 迭代器通常被稱爲“輕量級”對象, 因爲創建它的代價小。 Java中的Iterator功能比較簡單, 並且只能單向移動: (1) 使用方法iterator()要求容器返回一個Iterator。 第一次調用Iterator的next()方法時, 它返回序列的第一個元素。 注意:iterator()方法是java.lang.Iterable接口 被Collection繼承。 (2) 使用next()獲得序列中的下一個元素。 (3) 使用hasNext()檢查序列中是否還有元素。 (4) 使用remove()將迭代器新返回的元素刪除。 Iterator是Java迭代器最簡單的實現, 爲List設計的ListIterator具有更多的功能, 它可以從兩個方向遍歷List, 也可以從List中插入和刪除元素。 ------------- ListIterator的特點: 它的父類接口是Iterator, 名稱是系列表迭代器, 允許程序員按任一方向遍歷列表、 迭代期間修改列表, 並獲得迭代器在列表中的當前位置。 ListIterator沒有當前元素, 它的光標位置始終位於調用previous() 所返回的元素和調用next() 所返回的元素之間。 長度爲n的列表的迭代器有n+1個 可能的指針位置。 ------------------ Enumeration的特點: API中是這樣描述的, 它主要是和Vector結合配套使用。 另外此接口的功能與Iterator接口的功能是重複的, 此外,Iterator接口添加了 一個可選的移除操作, 並且使用較短的方法名。 新的實現應該優先 考慮使用Iterator接口 而不是Enumeration接口。 ----------------------- java中的集合類都提供了 返回Iterator的方法, 就是迭代器, 它和Enumeration的主要區別 其實就是Iterator可以刪除元素, 但是Enumration卻不能。 

42.Java 中 Set 與 List 有什麼不同?

 
1、Set 不允許重複,List允許重複 2、Set 沒有順序,List有順序 List接口對Collection進行了簡單的擴充, 它的具體實現類常用的有ArrayList和LinkedList。 你可以將任何東西放到一個List容器中, 並在需要時從中取出。 ArrayList從其命名中可以看出 它是一種類似數組的形式進行存儲, 因此它的隨機訪問速度極快, 而LinkedList的內部實現是鏈表, 它適合於在鏈表中間 需要頻繁進行插入和刪除操作。 在具體應用時可以根據需要自由選擇。 前面說的Iterator只能對容器進行向前遍歷, 而ListIterator則繼承了Iterator的思想, 並提供了對List進行雙向遍歷的方法。 Set接口也是Collection的一種擴展, 而與List不同的時, 在Set中的對象元素不能重複, 也就是說你不能把同樣的東西 兩次放入同一個Set容器中。 它的常用具體實現有HashSet和TreeSet類。 HashSet能快速定位一個元素, 但是你放到HashSet中的對象 需要實現hashCode()方法, 它使用了前面說過的哈希碼的算法。 而TreeSet則將放入 其中的元素按序存放, 這就要求你放入 其中的對象是可排序的, 這就用到了集合框架提供的 另外兩個實用類Comparable和Comparator。 一個類是可排序的, 它就應該實現Comparable接口。 有時多個類具有相同的排序算法, 那就不需要在每分別重複定義 相同的排序算法, 只要實現Comparator接口即可。 集合框架中還有兩個很實用的公用類: Collections和Arrays。 Collections提供了對一個Collection容器 進行諸如排序、複製、查找和填充等 一些非常有用的方法, Arrays則是對一個數組進行類似的操作。 

43.arraylist 與 vector 的區別?

 
ArrayList與Vector的區別, 這主要包括兩個方面:. 1.同步性: Vector是線程安全的, 也就是說是它的方法之間是線程同步的, 而ArrayList是線程序不安全的, 它的方法之間是線程不同步的。 如果只有一個線程會訪問到集合, 那最好是使用ArrayList, 因爲它不考慮線程安全, 效率會高些; 如果有多個線程會訪問到集合, 那最好是使用Vector, 因爲不需要我們自己 再去考慮和編寫線程安全的代碼。 備註: 對於Vector&ArrayList、Hashtable&HashMap, 要記住線程安全的問題, 記住Vector與Hashtable是舊的, 是java一誕生就提供了的, 它們是線程安全的, ArrayList與HashMap是java2時才提供的, 它們是線程不安全的。 2.數據增長: ArrayList與Vector 都有一個初始的容量大小, 當存儲進它們裏面的元素的個數超過了容量時, 就需要增加ArrayList與Vector的存儲空間, 每次要增加存儲空間時, 不是隻增加一個存儲單元, 而是增加多個存儲單元, 每次增加的存儲單元的個數 在內存空間利用與程序效率之間 要取得一定的平衡。 Vector默認增長爲原來兩倍, 而ArrayList的增長策略 在文檔中沒有明確規定 從源代碼看到的是增長爲原來的1.5倍。 ArrayList與Vector都可以設置初始的空間大小, Vector還可以設置增長的空間大小, 而ArrayList沒有提供 設置增長空間的方法。 總結: 即Vector增長原來的一倍, ArrayList增加原來的0.5倍。 

44.什麼類實現了List接口?

 
List接口的實現類中 最經常使用最重要的就是這三個: ArrayList、 Vector、 LinkedList。 1.三個都直接實現了AbstractList這個抽象類 2,ArrayList和Vector都實現了 RandomAccess接口。 而LinkedList沒有。 這是什麼意思呢? 在JDK 中, RandomAccess接口是一個空接口, 所以它沒有實際意義。就是一個標記, 標記這個類支持高速隨機訪問, 所以,arrayList和 vector是支持隨機訪問的, 可是LinkedList不支持持 3.serializbale接口表明他們都支持序列化。 

這裏推薦一下我的Java後端高級技術羣:479499375 ,羣裏有(Java高架構、分佈式架構、高可擴展、高性能、高併發、性能優化、Spring boot、Redis、ActiveMQ、等學習資源)進羣免費送給每一位Java小夥伴,不管你是轉行,還是工作中想提升自己能力都可以!

45.什麼類實現了Set接口?

 
HashSet LinkedHashSet TreeSet HashSet是使用哈希表(hash table)實現的, 其中的元素是無序的。 HashSet的 add、 remove、 contains方法 的時間複雜度爲常量O(1)。 -------------------- TreeSet使用樹形結構 算法書中的紅黑樹red-black tree 實現的。 TreeSet中的元素是可排序的, 但add、remove和contains方法的時間 複雜度爲O(log(n))。 TreeSet還提供了 first()、 last()、 headSet()、 tailSet()等 方法來操作排序後的集合。 ----------------------- LinkedHashSet介於HashSet和TreeSet之間。 它基於一個由鏈表實現的哈希表, 保留了元素插入順序。 LinkedHashSet中基本方法的 時間複雜度爲O(1)。 

46.如何保證一個集合線程安全?

 
Java提供了不同層面的線程安全支持。 在傳統集合框架內部, 除了Hashtable等同步容器, 還提供了所謂的同步包裝器(Synchronized Wrapper), 可以調用Collections工具類提供的包裝方法, 來獲取一個同步的包裝容器, 例如Collections.synchronizedMap()。 但是它們都是利用非常粗粒度的同步方式, 在高併發情況下的性能比較低下。 另外,更加普遍的選擇是利用併發包(java.util.concurrent) 提供的線程安全容器類: 各種併發容器, 比如ConcurrentHashMap、 CopyOnWriteArrayList。 各種線程安全隊列(Queue/Deque), 比如ArrayBlockingQueue、 SynchronousQueue。 各種有序容器的線程安全版本等。 具體保證線程安全的方式, 包括有從簡單的synchronized方式, 到基於更加精細化的, 比如基於分離鎖實現的ConcurrentHashMap等併發實現等。 具體選擇要看開發的場景需求, 總體來說, 併發包內提供的容器通用場景, 遠遠優於早期的簡單同步實現。 爲什麼需要ConcurrentHashMap 首先,Hashtable本身比較低效, 因爲它的實現基本就是 將put、get、size等方法 簡單粗暴地加上“synchronized”。 這就導致了所有併發操作都要競爭同一把鎖, 一個線程在進行同步操作時, 其它線程只能等待, 大大降低了併發操作的性能。 

47.是否可以往 TreeSet 或者 HashSet 中添加 null 元素?

 
1.TreeSet 是二差樹實現的, Treeset中的數據是自動排好序的, 不允許放入null值 2.HashSet 是哈希表實現的, HashSet中的數據是無序的, 可以放入null, 但只能放入一個null, 兩者中的值都不能重複, 就如數據庫中唯一約束 3.HashSet要求放入的對象 必須實現HashCode()方法, 放入的對象,是以hashcode碼作爲標識的, 而具有相同內容的String對象, hashcode是一樣, 所以放入的內容不能重複。 但是同一個類的對象可以放入不同的實例 

48.hashCode() 和 equals() 方法的重要性?如何在Java中使用它們?

 
Java中的HashMap使用 hashCode()和equals()方法 來確定鍵值對的索引, 當根據鍵獲取值的時候 也會用到這兩個方法。 如果沒有正確的實現這兩個方法, 兩個不同的鍵可能會有相同的hash值, 因此可能會被集合認爲是相等的。 而且,這兩個方法也用來發現重複元素, 所以這兩個方法的實現對HashMap的 精確性和正確性是至關重要的。 同一個對象(沒有發生過修改) 無論何時調用hashCode(), 得到的返回值必須一樣。 hashCode()返回值相等, 對象不一定相等, 通過hashCode()和equals() 必須能唯一確定一個對象。 一旦重寫了equals(), 就必須重寫hashCode()。 而且hashCode()生成哈希值的依據應該是 equals()中用來比較是否相等的字段。 如果兩個由equals()規定相等的對象 生成的hashCode不等, 對於HashMap來說, 他們可能分別映射到不同位置, 沒有調用equals()比較是否相等的機會, 兩個實際上相等的對象可能被插入到不同位置, 出現錯誤。 其他一些基於哈希方法的集合類 可能也會有這個問題。 ---------------- 怎麼判斷兩個對象是相同的? 使用等號== 判斷兩個對象是否相同, 這種是嚴格的相同, 即內存中的同一個對象  Object的equal方法就是使用==判斷兩個對象是否相同 ------------ 集合set要求元素是唯一的,怎麼實現? 要實現元素的唯一, 需要在往集合set中添加元素時, 判斷集合set是否存在相同的元素, 如果存在,則不添加,反之。 那麼怎麼確定兩個元素是否相同, 1.如果是使用等號==判斷兩個元素是否相同, 即默認使用Object的equals的方法。 2.如果沒有使用等號==判斷兩個元素是否相同, 而是按照某種業務規則判斷兩個元素是否相同, 即重寫了Object的equals的方法。 ---------------------- 當重寫equals方法,必須重寫hashCode方法嗎? 不是必須的, 得看具體的情況 當equals方法返回的結果和使用等號 比較的結果是一致的時候, 是沒有必要重寫hashCode方法。 當用等號比較對象, 只有是內存中同一個對象實例, 纔會返回true, 當然調用其hashCode()方法 肯定返回相同的值, 這滿足了滿足了hashCode的約束條件, 所以不用重寫hashCode()方法。 當equals方法返回的結果 和使用等號比較的結果是不一致的時候, 就需要重寫hashCode方法。 當重寫後的equals方法 不認爲只有是在內存中同一個對象實例, 才返回true, 如果不重新hashCode方法() Object的hashCode()方法 是對內存地址的映射, hashCode方法返回的值肯定是不同的, 這違背了hashCode的約束條件, 所以必須要重新hashCode方法, 並滿足對hashCode的約束條件。 

49.array 和 arraylist 的區別?

 
兩者間的區別: Array 的容量是固定的, ArrayList 的容量是根據需求自動擴展 ArrayList 提供了 添加、插入或移除 某一範圍元素的方法 而 Array 中, 只能一次獲取或設置一個元素值 用Synchronized方法可以 很容易地創建ArrayList的同步版本 而 Array 將一直保持 它知道用戶實現同步爲止 array 數組的用法 type [] name = new type [size]; 注意:size不能省略,type前後要一致 缺點:在數據間插入數據是 ArrayList 動態數組的用法 是 Array 的複雜版本 動態的增加和減少元素, 實現 ICollection 和 IList 接口 靈活的設置數組大小 

50.如何將一個字符串轉換爲arraylist?

 
string 轉 ArrayList 先將字符串按照某個字符切割,轉爲string數組 然後用Arrays的asList方法,將數組轉爲List public class test1 { public static void main(String[] args) { //string 轉 ArrayList String str1 = "a,b,c"; ArrayList<String> list = new ArrayList<String>(Arrays.asList(str1.split(","))); System.out.println(list); } } ArrayList 轉 string public class test1 { public static void main(String[] args) { //ArrayList 轉 string ArrayList<String> list = new ArrayList<String>(); list.add("a"); list.add("b"); list.add("c"); System.out.println(list);//[a, b, c] String list_str = StringUtils.join(list,","); System.out.println(list_str);//a,b,c } }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章