俗话说 “学而不思则罔”,是时候复习和整理一下自己先前的学习历程了!
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条件直接退出循环了,然后放回直接没有找到的该目标值。因此为了避免这种情况的发生,我们应该加上等于号。
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()); //输出累加的结果!
}