复制数组
复制数组有两种:一只是把引用指向了旧数组,如果旧数组改变新数组就会改变。二把旧数组Copy一份,让堆内存里有两个一模一样的数组,只是一样,没有任何指向关系,改变一个也不会改变另一个
先看Arrays.copyOf的源码
public static int[] copyOf(int[] original, int newLength) {
int[] copy = new int[newLength];
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
新创建的数组引用给了System.arraycopy,
public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length);
这个Native关键字涉及到外部定义,可以这么理解,就是它去执行C语言里的方法去了,你肯定知道java的底层语言是C语言,也知道和java语言相比,C语言当然是快的,所以复制一个数组时用for循环不如用Array.copyOf性能更好
迭代时删除问题
对于集合我们有时经常用到for循环迭代,如果只是访问查询修改,不删除,那是没有问题的,但是如果有删除那就有大问题了
单线程模式下用map会很形象的演示出来
代码:
HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
map.put(1, 1);
map.put(2, 1);
map.put(3, 1);
map.put(4, 1);
map.put(5, 1);
map.put(6, 1);
for(int b : map.keySet()) {
map.remove(b);
}
报的错误:Exception in thread “main” java.util.ConcurrentModificationException
多线程模式下用list就可以演示出来
final ArrayList<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(1);
list.add(1);
list.add(1);
list.add(1);
list.add(1);
list.add(1);
list.add(1);
list.add(1);
list.add(1);
list.add(1);
list.add(1);
Thread t1=new Thread(new Runnable() {
public void run() {
for(int i : list) {
list.remove(i);
System.out.println("删除"+i);
}
}
});
Thread t2=new Thread(new Runnable() {
public void run() {
for(int i : list) {
System.out.println(list.get(i)+"===");
}
}
});
t1.start();
t2.start();
会报错和上面的一样:Exception in thread “Thread-0” java.util.ConcurrentModificationException