1. 程式人生 > >Java中陣列 列舉 內部類

Java中陣列 列舉 內部類

一, 陣列

一系列相同型別的元素
有序的
連續的記憶體空間
初始化時固定大小

使用方式

//new int[10] : 申請10個int的記憶體空間, 並初始化所有的元素為0
int[] a = new int[10];
//只有在宣告時使用
int[] b = {1, 2, 3, 4, 5};
//可以在非宣告時使用
int[] c = new int[]{1, 2, 3, 4, 5, 6};
System.out.println(c[0]);
//陣列長度
System.out.println(c.length);

陣列遍歷:

普通for迴圈, 增強for迴圈:

//陣列遍歷:
for (int i = 0; i < c.length; i++){
    System.out.println(c[i]);

}
//增強for迴圈: 只能訪問不能賦值
for (int i : c) {
    System.out.println(i);
}

注: IDEA中迴圈的快捷鍵
itar:普通迴圈遍歷
iter:增強for迴圈

案例

準備: 一種交換的寫法

    public static void swap(int[] a, int i, int j) {
        if
(i == j) { return; } //^異或 a[i] ^= a[j]; a[j] ^= a[i]; a[i] ^= a[j]; }

排序演算法

選擇排序

從0開始 , 把當前位置最小數位置, 然後從後面開始找到最小數, 跟當前位置的數交換

//選擇排序
private static void sort(int[] a) {
    for (int i = 0; i < a.length - 1; i++) {
        int min = i;//記錄最小位置
for (int j = i + 1; j < a.length; j++) { if (a[min] > a[j]) { min = j; } } if (min != i) { swap(a, i, min); } } }

插入排序

前面是排好序的, 將後續的數字插入到前面合適位置

//插入排序
private static void sort2(int[] a) {
    for (int i = 1; i < a.length; i++) {
        for (int j = i - 1; j >= 0; j--) {
            if (a[j + 1] < a[j]) {
                swap(a, j + 1, j);
            } else {
                break;
            }
        }
    }
}

氣泡排序

迴圈(n-1)次每次將最大的放到最後

//氣泡排序
private static void sort3(int[] a) {
    for (int i = a.length - 1; i > 0; i--) {
        for (int j = 0; j < i; j++) {
            if (a[j] > a[j + 1]) {
                swap(a, j, j + 1);
            }
        }
    }
}

快速排序

隨機選擇一個下標,通過該下標將陣列分成兩個陣列, 將比該下標下的數值小的放在前面, 大的放到後面

步驟:

  只考慮迴圈一次, 首先找個隨機值(陣列下標以內)index, 找到將index位置的數和end位置的交換, 之後將start的值賦值給index, 此時index表示要插入的位置, 然後用index位置的值迴圈跟end位置的值進行比較, 比end位置值大的不動, 小的就將該位置的值與index位置的值交換,當該迴圈結束後說明, 說明index左邊小, 右邊大, 將end位置值與index交換

//快速排序
private static Random random;
private static void qSort(int[] a) {
    qSort(a, 0, a.length - 1);
}

private static void qSort(int[] a, int start, int end) {
    //遞迴出口
    if (start >= end) {
        return;
    }

    //隨機一個數字
    int index = random.nextInt(end - start + 1) + start;
    //和最後一位交換位置
    swap(a, index, end);
    index = start;
    for (int i = start; i < end; i++) {
        if (a[i] < a[end]) {
            swap(a, index, i);
            index++;
        }
    }
    swap(a, index, end);
    qSort(a, start, index - 1);
    qSort(a, index + 1, end);
}

二, 列舉

定義一些不太好定義的量, 例如,一週中的七天或者人類中的性別等等
列舉中可以有屬性和方法
列舉型別和類最大的區別就是: 列舉型別是不能被new出來的!!!!!!
列舉型別可以重寫方法
可以用switch做分支
列舉的預設的構造方法時private, 並且不能修改!

public enum Gender {
    MALE, FEMALE
}

switch (human.getGender()) {
    case FEMALE:
        System.out.println("男");
        break;
    case MALE:
        System.out.println("女");
        break;
}

典型的例子

public enum Gender {
    MALE("男性"){
        @Override
        public String getChinese() {
            return "重寫getChinese方法 " + "男性";
        }
    }, FEMALE("女性");
    private String chinese;

    Gender(String chinese){
        this.chinese = chinese;
    }
    public String getChinese() {
        return chinese;
    }
}

測試

System.out.println(Gender.MALE);
System.out.println(Gender.MALE.getChinese());

類載入到記憶體的時機: 建立物件 和 使用類中靜態屬性或方法, 其中宣告變數不算

new Human();
Human.getInstance();

單例設計模式

懶漢式

用到例項的時候建立

 public static synchronized Human getInstance() {
        //懶漢式
        if (instance == null) {
            instance = new Human();
        }
        return instance;
    }
    private Human() {
    }
}

餓漢式

類被第一次使用時建立


//放在靜態程式碼塊中可以初始化該類的物件
//類被第一次使用時呼叫
private static Human instance;
static {
    instance = new Human();
    //此時可以進行預設值操作
    instance.setAge(18);
    instance.setHeight(1.7f);
    instance.setGender(Gender.MALE);
}
public static synchronized Human getInstance() {
    return instance;
}
private Human() {
}

以上方法不能絕對保證它是單例, 可以通過反射機制獲取到新的例項
我們可以通過下面的列舉實現完全的單例模式!


public enum Human02 {
    instance;
    private int age;
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    static {
        instance.setAge(18);
    }
    public static Human02 getInstance(){
        return instance;
    }
    Human02(){
    }
}

三, 內部類

內部類分為靜態內部類和靜態外部類

靜態內部類

使用方式和普通類完全一樣. 可以使用外部類中所有的靜態屬性和方法以及所有的構造方法.

構建者設計模式

構建者設計模式就是通過靜態內部類實現:
以下案例是用來解決 建立使用者時必填項和選填項的問題

使用者類

public class User {
    private String userName;
    private String password;
    private String nickName;
    private int age;
    private Gender gender;
    private String email;

    private User(String userName, String password, String nickName, int age, Gender gender, String email) {
        this.userName = userName;
        this.password = password;
        this.nickName = nickName;
        this.age = age;
        this.gender = gender;
        this.email = email;
    }

    //靜態內部類
    //使用方法, 和普通類完全一樣
    //可以使用外部類中所有的靜態的屬性和所有的構造方法
    public static class Builder {
        private String userName;
        private String password;
        private String nickName;
        private int age;
        private Gender gender;
        private String email;

        public Builder(String userName, String password) {
            this.userName = userName;
            this.password = password;
        }

        public Builder setNickName(String nickName) {
            this.nickName = nickName;
            return this;
        }

        public Builder setAge(int age) {
            this.age = age;
            return this;
        }

        public Builder setGender(Gender gender) {
            this.gender = gender;
            return this;
        }

        public Builder setEmail(String email) {
            this.email = email;
            return this;
        }
        public User build(){
            return new User(userName, password, nickName, age, gender, email);

        }

    }
}

測試類

 public static void main(String[] args) {
        User user = 
            new User.Builder("user", "123456").
            setAge(10).
            setGender(Gender.MALE).
            build();
  }

非靜態內部類

注意下面幾點

  • 建立一個內部類物件的時候一定要先有一個外部類的物件
  • 可以訪問外部類的所有屬性和方法
  • 在非靜態內部類中, this為內部類當前物件, 外部類.this為外部類的當前物件
  • 內部類物件是由誰(外部類)建立的, 那麼它就從屬於該外部類

匿名內部類

匿名內部類在Android中經常使用

在匿名內部類中, 只能建立一個物件