java面試題:數據存儲(集合)

java面試題:數據存儲

數據存儲存在一個演進的過程,**從最初的變量存儲一個數據,到數組可以存放多個數據,到集合可以任意存放多個數據,**其演變過程一點點的解決了面臨的困難。

變量:

基本格式:

數據類型 變量名=變量值

缺點:一次只能賦值一個數據,如果多個數據就只能定義多個變量

數組:

數組特點:

1.是一種引用數據類型

2.數組當中的多個數據,類型必須統一

3.數組的長度在程序運行期間不可改變

缺點:數組的長度在程序運行期間不可改變

數組初始化:

動態初始化: 指定數組的長度

數據類型[] 數組名稱=new 數據類型[數組長度]

靜態初始化:指定數組的內容

數據類型[] 數組名稱=new 數據類型[]{元素1,元素2}
省略格式:
數據類型[] 數組名稱={元素1,元素2}

數組的賦值與取值

使用動態初始化數組時候,元素默認擁有一個默認值,

如果是整數類型,默認爲0;

如果是浮點類型,默認是0.0;

如果是字符類型,默認是‘\u0000’

如果是blean類型,默認是false

如果是引用類型,默認是null

賦值:array[1]=123;

獲取:sout(array[0]);

數組常用方法:

獲取長度:array.lenth

數組最值:

int max=array[0];
        for (int i = 1; i < array.length; i++) {
           if (array[i]>max){
               max=array[i];
           }
        }

數組反轉:

for (int min=0,max=array.length-1;min<max;min++,max--){
            int temp=array[min];
            array[min]=array[max];
            array[max]=temp;
        }

集合:

集合頂層接口:

集合按照其存儲結構可以分爲兩大類,分別是單列集合java.util.Collection和雙列集合java.util.Map

Collection:單列集合類的根接口,用於存儲一系列符合某種規則的元素,它有兩個重要的子接口,分別是java.util.Listjava.util.Set。其中,List的特點是元素有序、元素可重複。Set的特點是元素無序,而且不可重複。List接口的主要實現類有java.util.ArrayListjava.util.LinkedListSet接口的主要實現類有java.util.HashSetjava.util.TreeSet

Collection是所有單列集合的父接口,因此在Collection中定義了單列集合(List和Set)通用的一些方法,這些方法可用於操作所有的單列集合。方法如下:

  • public boolean add(E e): 把給定的對象添加到當前集合中 。
  • public void clear() :清空集合中所有的元素。
  • public boolean remove(E e): 把給定的對象在當前集合中刪除。
  • public boolean contains(E e): 判斷當前集合中是否包含給定的對象。
  • public boolean isEmpty(): 判斷當前集合是否爲空。
  • public int size(): 返回集合中元素的個數。
  • public Object[] toArray(): 把集合中的元素,存儲到數組中。

map:現實生活中,我們常會看到這樣的一種集合:IP地址與主機名,身份證號與個人,系統用戶名與系統用戶對象等,這種一一對應的關係,就叫做映射。Java提供了專門的集合類用來存放這種對象關係的對象,即java.util.Map接口。

我們通過查看Map接口描述,發現Map接口下的集合與Collection接口下的集合,它們存儲數據的形式不同,如下圖。
在這裏插入圖片描述

  • Collection中的集合,元素是孤立存在的(理解爲單身),向集合中存儲元素採用一個個元素的方式存儲。
  • Map中的集合,元素是成對存在的(理解爲夫妻)。每個元素由鍵與值兩部分組成,通過鍵可以找對所對應的值。
  • Collection中的集合稱爲單列集合,Map中的集合稱爲雙列集合。
  • 需要注意的是,Map中的集合不能包含重複的鍵,值可以重複;每個鍵只能對應一個值。

面試題1:如何遍歷list,set集合:

使用迭代器:

下面介紹一下迭代的概念:

  • 迭代:即Collection集合元素的通用獲取方式。在取元素之前先要判斷集合中有沒有元素,如果有,就把這個元素取出來,繼續在判斷,如果還有就再取出出來。一直把集合中的所有元素全部取出。這種取出方式專業術語稱爲迭代。

想要遍歷Collection集合,那麼就要獲取該集合迭代器完成迭代操作,下面介紹一下獲取迭代器的方法:

  • public Iterator iterator(): 獲取集合對應的迭代器,用來遍歷集合中的元素的。

Iterator接口的常用方法如下:

  • public E next():返回迭代的下一個元素。
  • public boolean hasNext():如果仍有元素可以迭代,則返回 true。

使用增強for循環:

增強for循環(也稱for each循環)是JDK1.5以後出來的一個高級for循環,專門用來遍歷數組和集合的。它的內部原理其實是個Iterator迭代器,所以在遍歷的過程中,不能對集合中的元素進行增刪操作。

格式:

for(元素的數據類型  變量 : Collection集合or數組){ 
  	//寫操作代碼
}

它用於遍歷Collection和數組。通常只進行遍歷元素,不要在遍歷的過程中對集合元素進行增刪操作。

Collection接口子類

List

List作爲Collection集合的子接口,不但繼承了Collection接口中的全部方法,而且還增加了一些根據元素索引來操作集合的特有方法,如下:

  • public void add(int index, E element): 將指定的元素,添加到該集合中的指定位置上。
  • public E get(int index):返回集合中指定位置的元素。
  • public E remove(int index): 移除列表中指定位置的元素, 返回的是被移除的元素。
  • public E set(int index, E element):用指定元素替換集合中指定位置的元素,返回值的更新前的元素。

LinkedList

java.util.LinkedList集合數據存儲的結構是鏈表結構。方便元素添加、刪除的集合。
在這裏插入圖片描述

實際開發中對一個集合元素的添加與刪除經常涉及到首尾操作,而LinkedList提供了大量首尾操作的方法。這些方法我們作爲了解即可:

  • public void addFirst(E e):將指定元素插入此列表的開頭。
  • public void addLast(E e):將指定元素添加到此列表的結尾。
  • public E getFirst():返回此列表的第一個元素。
  • public E getLast():返回此列表的最後一個元素。
  • public E removeFirst():移除並返回此列表的第一個元素。
  • public E removeLast():移除並返回此列表的最後一個元素。
  • public E pop():從此列表所表示的堆棧處彈出一個元素。
  • public void push(E e):將元素推入此列表所表示的堆棧。
  • public boolean isEmpty():如果列表不包含元素,則返回true。

LinkedList是List的子類,List中的方法LinkedList都是可以使用,這裏就不做詳細介紹,我們只需要瞭解LinkedList的特有方法即可。在開發時,LinkedList集合也可以作爲堆棧,隊列的結構使用。(瞭解即可)

ArrayList

java.util.ArrayList集合數據存儲的結構是數組結構。元素增刪慢,查找快,由於日常開發中使用最多的功能爲查詢數據、遍歷數據,所以ArrayList是最常用的集合。

set

java.util.Set接口和java.util.List接口一樣,同樣繼承自Collection接口,它與Collection接口中的方法基本一致,並沒有對Collection接口進行功能上的擴充,只是比Collection接口更加嚴格了。與List接口不同的是,Set接口中元素無序,並且都會以某種規則保證存入的元素不出現重複。

Set集合有多個子類,這裏我們介紹其中的java.util.HashSetjava.util.LinkedHashSet這兩個集合。

boolean add(E e) 如果此 set 中尚未包含指定元素,則添加指定元素。
void clear() 從此 set 中移除所有元素。
Object clone() 返回此 HashSet 實例的淺表副本:並沒有複製這些元素本身。
boolean contains(Object o) 如果此 set 包含指定元素,則返回 true
boolean isEmpty() 如果此 set 不包含任何元素,則返回 true
Iterator<E> iterator() 返回對此 set 中元素進行迭代的迭代器。
boolean remove(Object o) 如果指定元素存在於此 set 中,則將其移除。
int size() 返回此 set 中的元素的數量(set 的容量)。

LinkedHashSet

我們知道HashSet保證元素唯一,可是元素存放進去是沒有順序的

HashSet

在HashSet下面有一個子類java.util.LinkedHashSet,它是鏈表和哈希表組合的一個數據存儲結構。

HashSet是根據對象的哈希值來確定元素在集合中的存儲位置,因此具有良好的存取和查找性能。保證元素唯一性的方式依賴於:hashCodeequals`方法。

Collections

  • java.utils.Collections是集合工具類,用來對集合進行操作。部分方法如下:

  • public static <T> boolean addAll(Collection<T> c, T... elements):往集合中添加一些元素。

  • public static void shuffle(List<?> list) 打亂順序:打亂集合順序。

  • public static <T> void sort(List<T> list):將集合中元素按照默認規則排序。

  • public static <T> void sort(List<T> list,Comparator<? super T> ):將集合中元素按照指定規則排序。

Comparator比較器

面試題2:簡述Comparable和Comparator兩個接口的區別。

Comparable:強行對實現它的每個類的對象進行整體排序。這種排序被稱爲類的自然排序,類的compareTo方法被稱爲它的自然比較方法。只能在類中實現compareTo()一次,不能經常修改類的代碼實現自己想要的排序。實現此接口的對象列表(和數組)可以通過Collections.sort(和Arrays.sort)進行自動排序,對象可以用作有序映射中的鍵或有序集合中的元素,無需指定比較器。

Comparator強行對某個對象進行整體排序。可以將Comparator 傳遞給sort方法(如Collections.sort或 Arrays.sort),從而允許在排序順序上實現精確控制。還可以使用Comparator來控制某些數據結構(如有序set或有序映射)的順序,或者爲那些沒有自然順序的對象collection提供排序。

map:

Map常用子類

通過查看Map接口描述,看到Map有多個子類,這裏我們主要講解常用的HashMap集合、LinkedHashMap集合。

  • HashMap<K,V>:存儲數據採用的哈希表結構,元素的存取順序不能保證一致。由於要保證鍵的唯一、不重複,需要重寫鍵的hashCode()方法、equals()方法。
  • LinkedHashMap<K,V>:HashMap下有個子類LinkedHashMap,存儲數據採用的哈希表結構+鏈表結構。通過鏈表結構可以保證元素的存取順序一致;通過哈希表結構可以保證的鍵的唯一、不重複,需要重寫鍵的hashCode()方法、equals()方法。

tips:Map接口中的集合都有兩個泛型變量<K,V>,在使用時,要爲兩個泛型變量賦予數據類型。兩個泛型變量<K,V>的數據類型可以相同,也可以不同。

Map接口中的常用方法

Map接口中定義了很多方法,常用的如下:

  • public V put(K key, V value): 把指定的鍵與指定的值添加到Map集合中。
  • public V remove(Object key): 把指定的鍵 所對應的鍵值對元素 在Map集合中刪除,返回被刪除元素的值。
  • public V get(Object key) 根據指定的鍵,在Map集合中獲取對應的值。
  • boolean containsKey(Object key) 判斷集合中是否包含指定的鍵。
  • public Set<K> keySet(): 獲取Map集合中所有的鍵,存儲到Set集合中。
  • public Set<Map.Entry<K,V>> entrySet(): 獲取到Map集合中所有的鍵值對對象的集合(Set集合)。

使用put方法時,若指定的鍵(key)在集合中沒有,則沒有這個鍵對應的值,返回null,並把指定的鍵值添加到集合中;

若指定的鍵(key)在集合中存在,則返回值爲集合中鍵對應的值(該值爲替換前的值),並把指定鍵所對應的值,替換成指定的新值。

面試題3:如何遍歷map集合

方法一:

鍵找值方式:即通過元素中的鍵,獲取鍵所對應的值

分析步驟:

  1. 獲取Map中所有的鍵,由於鍵是唯一的,所以返回一個Set集合存儲所有的鍵。方法提示:keyset()
  2. 遍歷鍵的Set集合,得到每一個鍵。
  3. 根據鍵,獲取鍵所對應的值。方法提示:get(K key)

方法二:

鍵值對方式:即通過集合中每個鍵值對(Entry)對象,獲取鍵值對(Entry)對象中的鍵與值。

操作步驟與圖解:

  1. 獲取Map集合中,所有的鍵值對(Entry)對象,以Set集合形式返回。方法提示:entrySet()
  2. 遍歷包含鍵值對(Entry)對象的Set集合,得到每一個鍵值對(Entry)對象。
  3. 通過鍵值對(Entry)對象,獲取Entry對象中的鍵與值。 方法提示:getkey() getValue()

面試題4:Vector & ArrayList的區別

vector是線程安全的,擴容時會翻倍
Arraylist則是多線程,擴容時會一半

面試題5:hashMap和hashtable的區別:

hashmap是非線程安全的,允許空值空鍵
hashtable是線程安全的,所以hashmap的效率高於hashtable; table不許空值空鍵

面試題6:Set,list ,conllection,conllections,map的區別:

map是一個接口,它是雙列的集合接口
List 和set都是接口,他們都繼承與接口conllection,
List是一個有序的可以存放重複的元素,有索引的集合
set是不能存儲重複數據的沒有索引也就是不能用普通for循環遍歷的集合;
conllection是單列集合的頂層接口;
conllections是一個封裝了衆多關於集合操作的靜態化方法的工具類

面試題7:解釋一下list接口及其子類的關係

List接口中有arraylist ,linkedlist 和vector
arraylist和vector都是基於數組實現的,查詢快,增刪改慢
linkedlist 是鏈表實現的,查詢慢,增刪改快

面試題8:解釋一下set接口及其子類的關係

set接口有一下子類:treeset、Hashset、linkedHashset
treeset、hashset集合:無序的集合,hashset底層是一個哈希表,treeset是使用了紅黑樹的哈希表
linkedhashset集合:有序集合。底層是一個哈希表和一個鏈表

面試題9:map及其子類的方式:

map是一個雙列接口,接口的實現類有hashmap,linkedhashmap,treemap
hashmap:實現的方式是哈希表,它是多線程的
linkedhashmap:實現方式是哈希表加上一個鏈表 本質上是一個數組加上一個雙列鏈表,
treemap實現的方式是紅黑樹的哈希表,

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