1. 程式人生 > >Java集合總結,泛型機制,可變引數

Java集合總結,泛型機制,可變引數

List實現類的區別及適用場景

  底層實現 優缺點 執行緒是否安全 效率 適用場景
ArrayList 陣列 查詢易,增刪難 單執行緒,多查詢,少增刪的程式
Vector 陣列 查詢易,增刪難 多執行緒,多查詢,少增刪的程式
LinkdeList 連結串列 查詢難,增刪易 單執行緒,多增刪,少查詢的程式

泛型

提問:什麼是泛型

回答:所謂泛型就是指是一種把型別的明確放到建立該類物件的時候或者呼叫該類方法的時候在確定。請看下面這個例子

//定義一個泛型類
public class MyClass<T> {
    //一個T型別的變數
    T t;
}

class test{
    public static void main(String[] args) {
        //建立物件的時候定義該型別為String
        MyClass<String> stringMyClass = new MyClass<>();
        stringMyClass.t="ssss";
    }
}
public class MyClass<T> {
    T t;
    //定義一個泛型方法
    public void test(T t){
    }
}

class test{
    public static void main(String[] args) {
        //建立物件的時候定義該型別為String
        MyClass<Integer> stringMyClass = new MyClass<>();
            stringMyClass.test(Integer.valueOf(100));
    }
}

 提問:可以定義一個泛型介面嗎

 回答:當然可以,請看這裡

//定義一個泛型介面
public interface MyInterface<M> {
    void test(M m);
}

class Test implements MyInterface<String>{

    @Override
    public void test(String s) {
        System.out.println(s);
    }
}

提問:為什麼要使用泛型,直接定義不就好了嗎,這樣豈不多此一舉?

回答:既然不好理解,那我們看一段程式碼吧


//如果我們預先不知道需要定義的變數是什麼型別,我們就可以把它定義成Object型別,可以接收任意型別
public class ObjectDemo {
    private Object object;

    public Object getObject() {
        return object;
    }

    public void setObject(Object object) {
        this.object = object;
    }
}
class test {
    public static void main(String[] args) {
        ObjectDemo objectDemo = new ObjectDemo();
        objectDemo.setObject("object");//將型別設定為String
        //取值
        Object object = objectDemo.getObject();
        String s = (String) object;
        s.length();
    }
}

 繼續回答:上面這段程式碼雖然實現了可以接收任意的物件型別,但是在實際的使用中,會有型別轉換的問題。這樣就不是很方便的,所以泛型應運而生。

public class Demo<T> {
    private T t;

    public T getT() {
        return t;
    }

    public void setT(T t) {
        this.t = t;
    }
}
class TestDemo{
    public static void main(String[] args) {
        Demo<String> stringDemo = new Demo<>();
        stringDemo.setT("泛型");
        String t = stringDemo.getT();
        t.length();
    }
}

可變引數

基本格式:public void test(資料類...變數名) 

請看這麼一段程式碼:

public class ChangePara {
    public static void main(String[] args) {
        test(1.0);
        test(1.0,2.0);
        test(1.0,2.0,3.0);
    }

    //普通方法重寫
    public static void test(double d1) {
        System.out.println(d1);
    }

    public static void test(double d1, double d2) {
        System.out.println(d1 + d2);
    }

    public static void test(double d1, double d2, double d3) {
        System.out.println(d1 + d2 + d3);
    }
}

如果我說可變引數可以一句程式碼實現上面這一堆,你們會信嗎?不信不行,請看 

public class ChangePara {
    public static void main(String[] args) {
        test(1.0);
        test(1.0,2.0);
        test(1.0,2.0,3.0);
    }

    //可變引數
    public static void test(double...d){
        //TODo..
    }

}

提問:這麼厲害,究竟如何實現的?

回答:其實他的頂層是將引數存入一個數組當中,這樣就可以存下同一個型別的多個引數,成百上千都不是問題的。 

提問:ArrayList集合遍歷一共有幾種方式?

回答:應該有四種

再問:請分別用四種方式遍歷集合

public class ArrayListDemo {
    public static void main(String[] args) {
        ArrayList<String> arrayList = new ArrayList();
        arrayList.add("三國演義");
        arrayList.add("紅樓夢");
        arrayList.add("水滸傳");
        arrayList.add("西遊記");
        //遍歷方式1 普通for迴圈
        for (int i = 0; i <arrayList.size(); i++) {
            System.out.println(arrayList.get(i));
        }
        //方式2  迭代器遍歷
        Iterator iterator = arrayList.iterator(); //獲取迭代器物件
        while (iterator.hasNext()){//判斷是否存在
            System.out.println(iterator.next()); //獲取
        }
        //方式3  列表迭代器遍歷
        ListIterator listIterator = arrayList.listIterator();
        while (listIterator.hasNext()){
            System.out.println(listIterator.next());
        }
        //方式4 增強for迴圈遍歷
        for(String s : arrayList){
            System.out.println(s);
        }

    }
}