1. 程式人生 > >Java集合框架常見面試題總結

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 的區別

HashSet å HashMap åºå«

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()的相關規定:

  1. 如果兩個物件相等,則hashcode一定也是相同的
  2. 兩個物件相等,對兩個equals方法返回true
  3. 兩個物件有相同的hashcode值,它們也不一定是相等的
  4. 綜上,equals方法被覆蓋過,則hashCode方法也必須被覆蓋
  5. hashCode()的預設行為是對堆上的物件產生獨特值。如果沒有重寫hashCode(),則該class的兩個物件無論如何都不會等。
  6. "=="與equals的區別:
    1. ==是判斷兩個變數或例項是不是指向同一個記憶體空間 equals是判斷兩個變數或例項所指向的記憶體空間的值是不是
    2. ==是指對記憶體地址進行比較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;
import java.util.List;

/**
 * 功能:兩個集合之間求交集  並集  差集  去重複並集
 * @author lee
 * @dete  2018.10.29    
 * @version 1.7
 * */
public class Demo {

    public static void main(String[] args) {
        List<Integer>  list1=new ArrayList<>();
        list1.add(1);
        list1.add(2);
        list1.add(3);
        list1.add(4);
        
        List<Integer>  list2=new ArrayList<>();
        list2.add(2);
        list2.add(3);
        list2.add(4);
        list2.add(5);
        //並集
        System.out.println(list1.addAll(list2));
        //交集
        System.out.println(list1.retainAll(list2));
        //差集
        list1.removeAll(list2);
        //無重複集
        list2.removeAll(list1);
        list1.addAll(list2);
        for (Integer i : list2) {
            System.out.println(i);
        }
    }

}
 

集合框架底層資料結構總結

-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多看看。