Java集合框架常見面試題總結

圖片 (77).jpg

一. List,Set,Map三者的區別及總結

List:對付順序的好幫手java

List接口存儲一組不惟一(能夠有多個元素引用相同的對象),有序的對象面試

Set:注重獨一無二的性質算法

不容許重複的集合。不會有多個元素引用相同的對象。sql

Map:用Key來搜索的專家數組

使用鍵值對存儲。Map會維護與Key有關聯的值。兩個Key能夠引用相同的對象,但Key不能重複,典型的Key是String類型,但也能夠是任何對象。安全

二. Arraylist 與 LinkedList 區別

Arraylist底層使用的是數組(存讀數據效率高,插入刪除特定位置效率低),LinkedList底層使用的是雙向循環鏈表數據結構(插入,刪除效率特別高)。學過數據結構這門課後咱們就知道採用鏈表存儲,插入,刪除元素時間複雜度不受元素位置的影響,都是近似O(1)而數組爲近似O(n),所以當數據特別多,並且常常須要插入刪除元素時建議選用LinkedList.通常程序只用Arraylist就夠用了,由於通常數據量都不會蠻大,Arraylist是使用最多的集合類。數據結構

三. ArrayList 與 Vector 區別

Vector類的全部方法都是同步的。能夠由兩個線程安全地訪問一個Vector對象、可是一個線程訪問Vector ,代碼要在同步操做上耗費大量的時間。Arraylist不是同步的,因此在不須要同步時建議使用Arraylist。架構

四. HashMap 和 Hashtable 的區別

  1. HashMap是非線程安全的,HashTable是線程安全的;HashTable內部的方法基本都通過synchronized修飾。
  2. 由於線程安全的問題,HashMap要比HashTable效率高一點,HashTable基本被淘汰。
  3. HashMap容許有null值的存在,而在HashTable中put進的鍵值只要有一個null,直接拋出NullPointerException。

Hashtable和HashMap有幾個主要的不一樣:線程安全以及速度。僅在你須要徹底的線程安全的時候使用Hashtable,而若是你使用Java5或以上的話,請使用ConcurrentHashMap吧併發

五. 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的兩個對象不管如何都不會相等(即便這兩個對象指向相同的數據)。

==與equals的區別

  1. ==是判斷兩個變量或實例是否是指向同一個內存空間 equals是判斷兩個變量或實例所指向的內存空間的值是否是相同
  2. ==是指對內存地址進行比較 equals()是對字符串的內容進行比較3.==指引用是否相同 equals()指的是值是否相同

八. comparable 和 comparator的區別

  • comparable接口其實是出自java.lang包 它有一個 compareTo(Object obj)方法用來排序
  • comparator接口其實是出自 java.util 包它有一個compare(Object obj1, Object obj2)方法用來排序

通常咱們須要對一個集合使用自定義排序時,咱們就要重寫compareTo方法或compare方法,當咱們須要對某一個集合實現兩種排序方式,好比一個song對象中的歌名和歌手名分別採用一種排序方法的話,咱們能夠重寫compareTo方法和使用自制的Comparator方法或者以兩個Comparator來實現歌名排序和歌星名排序,第二種表明咱們只能使用兩個參數版的Collections.sort().

1. Comparator定製排序

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

/**
 * TODO Collections類方法測試之排序
 * @author 寇爽
 * @date 2017年11月20日
 * @version 1.8
 */
public class CollectionsSort {

    public static void main(String[] args) {

        ArrayList<Integer> arrayList = new ArrayList<Integer>();
        arrayList.add(-1);
        arrayList.add(3);
        arrayList.add(3);
        arrayList.add(-5);
        arrayList.add(7);
        arrayList.add(4);
        arrayList.add(-9);
        arrayList.add(-7);
        System.out.println("原始數組:");
        System.out.println(arrayList);
        // void reverse(List list):反轉
        Collections.reverse(arrayList);
        System.out.println("Collections.reverse(arrayList):");
        System.out.println(arrayList);
/*        
         * void rotate(List list, int distance),旋轉。
         * 當distance爲正數時,將list後distance個元素總體移到前面。當distance爲負數時,將
         * list的前distance個元素總體移到後面。
         
        Collections.rotate(arrayList, 4);
        System.out.println("Collections.rotate(arrayList, 4):");
        System.out.println(arrayList);*/
        
        // void sort(List list),按天然排序的升序排序
        Collections.sort(arrayList);
        System.out.println("Collections.sort(arrayList):");
        System.out.println(arrayList);

        // void shuffle(List list),隨機排序
        Collections.shuffle(arrayList);
        System.out.println("Collections.shuffle(arrayList):");
        System.out.println(arrayList);

        // 定製排序的用法
        Collections.sort(arrayList, new Comparator<Integer>() {

            @Override
            public int compare(Integer o1, Integer o2) {
                return o2.compareTo(o1);
            }
        });
        System.out.println("定製排序後:");
        System.out.println(arrayList);
    }

}

2. 重寫compareTo方法實現按年齡來排序

package map;

import java.util.Set;
import java.util.TreeMap;

public class TreeMap2 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        TreeMap<Person, String> pdata = new TreeMap<Person, String>();
        pdata.put(new Person("張三", 30), "zhangsan");
        pdata.put(new Person("李四", 20), "lisi");
        pdata.put(new Person("王五", 10), "wangwu");
        pdata.put(new Person("小紅", 5), "xiaohong");
        // 獲得key的值的同時獲得key所對應的值
        Set<Person> keys = pdata.keySet();
        for (Person key : keys) {
            System.out.println(key.getAge() + "-" + key.getName());

        }
    }
}

// person對象沒有實現Comparable接口,因此必須實現,這樣纔不會出錯,纔可使treemap中的數據按順序排列
// 前面一個例子的String類已經默認實現了Comparable接口,詳細能夠查看String類的API文檔,另外其餘
// 像Integer類等都已經實現了Comparable接口,因此不須要另外實現了

class Person implements Comparable<Person> {
    private String name;
    private int age;

    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = 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;
    }

    /**
     * TODO重寫compareTo方法實現按年齡來排序
     */
    @Override
    public int compareTo(Person o) {
        // TODO Auto-generated method stub
        if (this.age > o.getAge()) {
            return 1;
        } else if (this.age < o.getAge()) {
            return -1;
        }
        return age;
    }
}

九. 如何對Object的list排序

  • 對objects數組進行排序,咱們能夠用Arrays.sort()方法
  • 對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) :按指定集合的Iterator返回的順序將指定集合中的全部元素追加到此列表的末尾 實例代碼:
  • retainAll(Collection<?> c): 僅保留此列表中包含在指定集合中的元素。
  • removeAll(Collection<?> c) :今後列表中刪除指定集合中包含的全部元素。
package list;

import java.util.ArrayList;
import java.util.List;

/**
 *TODO 兩個集合之間求交集 並集 差集 去重複並集
 * @author 寇爽
 * @date 2017年11月21日
 * @version 1.8
 */
public class MethodDemo {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        List<Integer> list1 = new ArrayList<Integer>();
        list1.add(1);
        list1.add(2);
        list1.add(3);
        list1.add(4);

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

}

十二. 集合框架底層數據結構總結

1. Collection
①. List

  • Arraylist:數組(查詢快,增刪慢 線程不安全,效率高 )
  • Vector:數組(查詢快,增刪慢 線程安全,效率低 )
  • LinkedList:鏈表(查詢慢,增刪快 線程不安全,效率高 )

②. Set

  • HashSet(無序,惟一):哈希表或者叫散列集(hash table)
  • LinkedHashSet:鏈表和哈希表組成 。 由鏈表保證元素的排序 , 由哈希表證元素的惟一性
  • TreeSet(有序,惟一):紅黑樹(自平衡的排序二叉樹。)

2. Map

  • HashMap:基於哈希表的Map接口實現(哈希表對鍵進行散列,Map結構即映射表存放鍵值對)
  • LinkedHashMap:HashMap 的基礎上加上了鏈表數據結構
  • HashTable:哈希表
  • TreeMap:紅黑樹(自平衡的排序二叉樹)

十三. 集合的選用

主要根據集合的特色來選用,好比咱們須要根據鍵值獲取到元素值時就選用Map接口下的集合,須要排序時選擇TreeMap,不須要排序時就選擇HashMap,須要保證線程安全就選用ConcurrentHashMap.當咱們只須要存放元素值時,就選擇實現Collection接口的集合,須要保證元素惟一時選擇實現Set接口的集合好比TreeSet或HashSet,不須要就選擇實現List接口的好比ArrayList或LinkedList,而後再根據實現這些接口的集合的特色來選用。

寫在最後

限於篇幅,本文更新至此,文末送給你們一份小福利吧,應部分粉線私信須要Java面試題;故筆者整理了一份包含Kafka、Mysql、Tomcat、Docker、Spring、MyBatis、Nginx、Netty、Dubbo、Redis、Netty、Spring cloud、分佈式、高併發、性能調優、微服務等架構技術的面試題。

須要的朋友點擊下方傳送門, 便可免費領取面試資料和視頻學習資料

傳送門

如下是部分面試題截圖

相關文章
相關標籤/搜索