文章目錄
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.List
和java.util.Set
。其中,List
的特點是元素有序、元素可重複。Set
的特點是元素無序,而且不可重複。List
接口的主要實現類有java.util.ArrayList
和java.util.LinkedList
,Set
接口的主要實現類有java.util.HashSet
和java.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.HashSet
、java.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是根據對象的哈希值來確定元素在集合中的存儲位置,因此具有良好的存取和查找性能。保證元素唯一性的方式依賴於:
hashCode與
equals`方法。
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集合
方法一:
鍵找值方式:即通過元素中的鍵,獲取鍵所對應的值
分析步驟:
- 獲取Map中所有的鍵,由於鍵是唯一的,所以返回一個Set集合存儲所有的鍵。方法提示:
keyset()
- 遍歷鍵的Set集合,得到每一個鍵。
- 根據鍵,獲取鍵所對應的值。方法提示:
get(K key)
方法二:
鍵值對方式:即通過集合中每個鍵值對(Entry)對象,獲取鍵值對(Entry)對象中的鍵與值。
操作步驟與圖解:
- 獲取Map集合中,所有的鍵值對(Entry)對象,以Set集合形式返回。方法提示:
entrySet()
。 - 遍歷包含鍵值對(Entry)對象的Set集合,得到每一個鍵值對(Entry)對象。
- 通過鍵值對(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實現的方式是紅黑樹的哈希表,