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中經常使用
在匿名內部類中, 只能建立一個物件