Java集合框架常見面試題總結
List,Set,Map三者的區別及總結:
1.List:對付順序的好幫手
List介面儲存一組不唯一(可以有多個元素引用相同的物件),有序的物件
2.Set:注重獨一無二的性質:
不允許重複的集合。不會有多個元素引用相同的物件。
3.Map:用key來搜尋的專家
使用鍵值對儲存,Map會維護與key有關聯的值。兩個key可以引用相同的物件,但key不能重複,典型的key是String型別
但ye也可以是任何物件。
Arraylist 與 LinkedList 區別
Arraylist底層使用的是陣列(存讀資料效率高,插入刪除特定位置效率低),LinkedList底層使用的是雙向迴圈連結串列資料結構(插入,刪除效率特別高)。學過資料結構這門課後我們就知道採用連結串列儲存,插入,刪除元素時間複雜度不受元素位置的影響,都是近似O(1)而陣列為近似O(n),因此當資料特別多,而且經常需要插入刪除元素時建議選用LinkedList.一般程式只用Arraylist就夠用了,因為一般資料量都不會蠻大,Arraylist是使用最多的集合類。
ArrayList 與 Vector 區別
Vector類的所有方法都是同步的。可以由兩個執行緒安全地訪問一個Vector物件、但是一個執行緒訪問Vector ,程式碼要在同步操作上耗費大量的時間。Arraylist不是同步的,所以在不需要同步時建議使用Arraylist。
HashMap 和 Hashtable 的區別
HashMap 和 ConcurrentHashMap 的區別
1.ConcurrentHashMap對整個桶陣列進行了分割分段(Segment),然後在每一個分段上都用lock鎖進行保護,相對於HashTable的synchronized鎖的粒度更精細了一些,併發效能更好,而HashMap沒有鎖機制,不是執行緒安全的。(JDK1.8之後ConcurrentHashMap啟用了一種全新的方式實現,利用CAS演算法。)
2.HashMap的鍵值對允許有null,但是ConCurrentHashMap都不允許。
HashSet如何檢查重複
當你把物件加入HashSet時,HashSet會先計算物件的hashcode值來判斷物件加入的位置,同時也會與其他加入的物件的hashcode值作比較,如果沒有相符的hashcode,HashSet會假設物件沒有重複出現。但是如果發現有相同hashcode值的物件,這時會呼叫equals()方法來檢查hashcode相等的物件是否真的相同。如果兩者相同,HashSet就不會讓加入操作成功。
hashCode()與equals()的相關規定:
- 如果兩個物件相等,則hashcode一定也是相同的
- 兩個物件相等,對兩個equals方法返回true
- 兩個物件有相同的hashcode值,它們也不一定是相等的
- 綜上,equals方法被覆蓋過,則hashCode方法也必須被覆蓋
- hashCode()的預設行為是對堆上的物件產生獨特值。如果沒有重寫hashCode(),則該class的兩個物件無論如何都不會等。
- "=="與equals的區別:
- ==是判斷兩個變數或例項是不是指向同一個記憶體空間 equals是判斷兩個變數或例項所指向的記憶體空間的值是不是
- ==是指對記憶體地址進行比較equas()是對字串的內容比較
3.==指引用是否相同equals()指的是值是否相同。
comparable 和 comparator的區別
- comparable介面實際上是出自java.lang包 它有一個 compareTo(Object obj)方法用來排序
- comparator介面實際上是出自 java.util 包它有一個compare(Object obj1, Object obj2)方法用來排序
Comparator定製排序
package org.java.Test;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
/**
* 功能:Collections類方法測試之排序
* @author lee
* @date 2018.10.29
* @version 1.7
* */
public class CollectionsSort {
public static void main(String[] args) {
ArrayList<Integer> arr=new ArrayList<Integer>();
arr.add(-1);
arr.add(3);
arr.add(-5);
arr.add(7);
arr.add(4);
arr.add(-9);
arr.add(-7);
System.out.println("原始陣列:");
System.out.println(arr);
//void reverse(List list):反轉
Collections.reverse(arr);
System.out.println("Collections.reverse(arr):");
System.out.println(arr);
// void sort(List list),按自然排序的升序排序
Collections.sort(arr);
System.out.println("Collections.sort(arr):");
System.out.println(arr);
// void shuffle(List list),隨機排序
Collections.shuffle(arr);
System.out.println("Collections.sort(arr)");
System.out.println(arr);
//定製排序的用法
Collections.sort(arr,new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
// TODO Auto-generated method stub
return o2.compareTo(o1);
}
});
System.out.println("定製排序後:");
System.out.println(arr);
}
}
重寫compareTo方法實現按年齡來排序:
package org.java.Test;
import java.util.Set;
import java.util.TreeMap;
/**
* 功能:重寫compareto方法實現按年齡來排序
* @author lee
* @date 2018.10.29
*
* */
public class TreeMap2 {
public static void main(String[] args) {
TreeMap<Person,String> data=new TreeMap<Person,String>();
data.put(new Person("張三",30), "zhangsan");
data.put(new Person("李四",20), "lisi");
data.put(new Person("王五",18), "wangwu");
data.put(new Person("小紅",15), "xiaohong");
//得到key的值的同時得到key所對應的值
Set<Person> keys=data.keySet();
for (Person key : keys) {
System.out.println(key.getAge()+"-"+key.getName());
}
}
}
package org.java.Test;
public class Person implements Comparable<Person>{
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public int compareTo(Person o) {
if(this.age>o.getAge()){
return 1;
}else if(this.age<o.getAge()){
return -1;
}
return age;
}
}
如何對Object的list排序
1.對Objects陣列進行排序,我們可以用Arrays.sort()方法
2.對Objects的集合進行排序,需要使用Collections.sort()方法
如何實現陣列與List的相互轉換
List轉陣列:toArray(arraylist.size())方法;陣列轉List:Arrays的asList(a)方法
List<String> arrayList=new ArrayList<String>();
arrayList.add("s");
arrayList.add("e");
arrayList.add("n");
/** * ArrayList轉陣列 */ int size=arrayList.size(); String[] a = arrayList.toArray(new String[size]); //輸出第二個元素 System.out.println(a[1]);//結果:e //輸出整個陣列 System.out.println(Arrays.toString(a));//結果:[s, e, n] /** * 陣列轉list */ List<String> list=Arrays.asList(a); /** * list轉Arraylist */ List<String> arrayList2 = new ArrayList<String>(); arrayList2.addAll(list); System.out.println(list);
如何求ArrayList集合的交集 並集 差集 去重複並集
需要用到List介面中定義的幾個方法:
addAll(Collection<? Extends E > c):指定集合的iteator返回的順序將指定集合中的所有元素追加到此列表的末尾 例項程式碼:
retainAll(Collection<?> c):僅保留此列表中包含在指定集合中的元素。
removeAll(Collection<?> c):從此列表中刪除指定集合中包含的所有元素。
package org.java.Test; import java.util.ArrayList; /** public static void main(String[] args) { } |
集合框架底層資料結構總結
-Collection
1.List
ArrayList:陣列(查詢快,增刪慢 執行緒不安全,效率高)
Vector:陣列(查詢快,增刪慢 執行緒安全,效率低)
LinkedList:連結串列(查詢慢,增刪快 執行緒不安全,效率高)
2.Set
HashSet(無序,唯一):雜湊表或者san雜湊集(hash table)。
LinkedList:連結串列和雜湊表組成。由連結串列保證元素的排序,由雜湊表證元素的唯一性。
TreeSet(有序,唯一):紅黑樹(自平衡二叉樹)
-Map
HashMap:基於雜湊表的Map介面實現(雜湊表對鍵進行雜湊,Map結構即對映表存放鍵值對)。
LinkedHashMap:HashMap的基礎上加上了連結串列資料結構。
HashTable:雜湊表。
TreeMap:紅黑樹。
集合的選用.
主要根據集合的特點來選用,比如我們需要根據鍵值獲取到元素值時就選用Map介面下的集合,需要排序時選擇TreeMap,不需要排序時就選擇HashMap,需要保證執行緒安全就選用ConcurrentHashMap.當我們只需要存放元素值時,就選擇實現Collection介面的集合,需要保證元素唯一時選擇實現Set介面的集合比如TreeSet或HashSet,不需要就選擇實現List介面的比如ArrayList或LinkedList,然後再根據實現這些介面的特點來選用。
集合的常用方法
建議把API多看看。