俗话说 “学而不思则罔”,是时候复习和整理一下自己先前的学习历程了!
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 thoughtadd(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() {//checkif (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]);}}@Overridepublic Iterator<Integer> iterator() { // 迭代器return new Iterator<Integer>() {int i = 0;@Overridepublic boolean hasNext() { // 判断是否有下一个元素return i < size;}@Overridepublic 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
@Testpublic 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()); //输出累加的结果!}