俗話說 “學而不思則罔”,是時候複習和整理一下自己先前的學習歷程了!
Chapter-One
《BinarySearch》
public static int binarySearch (int[] a, int target) {
int i = 0, j = a.length - 1;
while (i <= j) {
int m = (i + j) >>> 1; // 求中位數,但是是用位運算子的方式,相對於除法,這種方式更加高效
if (target < a[m]) {
j = m - 1; // 如果找到的目標數小於中位數,則在中位數的左邊開始找起
} else if (a[m] < target){
i = m + 1; // 如果找到的目標數大於中位數,則在中位數的右邊開始找起
} else {
return m; // 找到則直接返回改數值在陣列中的索引的值
}
}
return -1; /* 沒有找到則直接返回-1,當然這裡選擇丟擲異常(並提示異常資訊,個人覺得對使用者體驗更加好 如: ) throw new RuntimeException("目標數值不在陣列中"); */
}
自問自答
問:為什麼while的條件中 i <= j 而不是 [instead of] i < j ?
答:1. 首先,顧名思義,前面的條件會比後面的條件多執行一次。
2. 那如果當 target == i == j 的時候呢,那少去的這一次就會因為不滿足while條件直接退出迴圈了,然後放回直接沒有找到的該目標值。因此為了避免這種情況的發生,我們應該加上等於號。
《DynamicArray》
import java.util.Arrays;
import java.util.Iterator;
import java.util.function.Consumer;
import java.util.stream.IntStream;
public class DynamicArray implements Iterable<Integer> {
private int size = 0; // 陣列中儲存元素的個數
private int capacity = 8; // 陣列的容量大小
private int[] array = {};
public void addLast(int element) { // 在陣列的尾部新增元素
// array[size] = element;
// size++; the original thought
add(size,element);
}
public void add(int index, int element) {
checkAndGrow(); // 判斷需要動態擴容的模式
if (index >=0 && index < size) {
System.arraycopy(array, index,
array, index + 1, size - index); // 使用java自帶的內建API,進行陣列的複製
} else if (index < 0) {
throw new RuntimeException("index typing wrong, retry again please!");
}
array[index] = element;// 指定的位置對元素進行新增
size++; // 更新陣列元素個數
}
private void checkAndGrow() {
//check
if (size == 0) {
array = new int[capacity];// 等於0時,預設初始化的容量
} else if (size == capacity) {
capacity += capacity >> 1; // 擴容1.5倍
int[] newArray = new int[capacity];
System.arraycopy(array, 0,
newArray, 0, size); // 陣列複製
array = newArray;
}
}
public int get(int index) { // 獲取陣列中指定的元素
return array[index];
}
public void foreach(Consumer<Integer> consumer) { //遍歷陣列元素
for (int i = 0; i < size; i++) {
consumer.accept(array[i]);
}
}
@Override
public Iterator<Integer> iterator() { // 迭代器
return new Iterator<Integer>() {
int i = 0;
@Override
public boolean hasNext() { // 判斷是否有下一個元素
return i < size;
}
@Override
public Integer next() { // 返回當前元素,並且指標向後面移動一位
return array[i++];
}
};
}
public IntStream stream() { // 將陣列轉成int位元組流
return IntStream.of(Arrays.copyOfRange(array,0,size)); //[0,size)
}
public int remove(int index) { //移除指定的 範圍:[0,size)
int removed = array[index];
if (index < size - 1) {
System.arraycopy(array, index + 1,
array, index, size - index - 1);
}
size--;
return removed;
}
}
自問自答
問:箭頭函式在這裡的用法?
答 1. foreach方法中定義的引數,類似一個集合的作用,把陣列中所有的遍歷之後的元素都存起來了
2. 因此在呼叫的階段,我們直接傳一個(whatever)形參,然後在 {程式碼塊中},我們可以對該引數做任何我們想做的事情或者實現想要實現的功能。
3. 相當於是,內部收集到了這個陣列的值,但是這個值有什麼用途,留給呼叫這個方法的使用者去決定了。
example
@Test
public void test2() {
DynamicArray dynamicArray = new DynamicArray();
AtomicInteger sum = new AtomicInteger(); // 把變數設定為原子狀態的Integer包裝型別
dynamicArray.addLast(1);
dynamicArray.addLast(2);
dynamicArray.addLast(3);
dynamicArray.addLast(4);
dynamicArray.forEach((element)->{
sum.addAndGet(element);// 對element的所有元素進行相加, 這裡返回值是int,但是我選擇不接收。
});
System.out.println(sum.get()); //輸出累加的結果!
}