Android开发经验谈Android开发Android开发

java基础----ArrayList,LinkedList,C

2018-08-20  本文已影响12人  pgydbh

总结

①ArrayList本质是顺序表,也就是数组
②LinkedList本质是链表,双向链表。查找的时候根据大小选择一半遍历。
③所以ArrayList的get效率高。
④所以LinkedList的put效率高。
⑤CopyOnWriteArrayList线程安全。ArrayList与LinkedList线程不安全。
⑥CopyOnWriteArrayList在写的时候加锁,保证了写的时候不会copy很多副本。
引用自:https://www.cnblogs.com/dolphin0520/p/3938914.html

什么是CopyOnWrite容器
  CopyOnWrite容器即写时复制的容器。通俗的理解是当我们往一个容器添加元素的时候,不直接往当前容器添加,而是先将当前容器进行Copy,复制出一个新的容器,然后新的容器里添加元素,添加完元素之后,再将原容器的引用指向新的容器。这样做的好处是我们可以对CopyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。所以CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器。

线程安全

ArrayList

中途报错,线程不安全。

    private static ArrayList<Integer> list = new ArrayList<>();
    private static ExecutorService executorService = Executors.newFixedThreadPool(20);
    public static void main(String[] args){

        for (int i = 0; i < 20; i++){
            executorService.execute(new MyRunnable());
        }
        executorService.shutdown();

        try {
            Thread.sleep(4000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(list.size());
    }

    private static class MyRunnable implements Runnable{

        @Override
        public void run() {
            for (int i = 0; i < 1000; i++){
                list.add(i);
            }
            System.out.println(list.size());
        }
    }
}

输出:
Exception in thread "pool-1-thread-3" java.lang.ArrayIndexOutOfBoundsException: 1950
    at java.util.ArrayList.add(ArrayList.java:463)
    at Main$MyRunnable.run(Main.java:43)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

linkedList

插入不完全,本来应该有20000个。线程不安全

public class Main{
    private static List<Integer> list = new LinkedList<>();
    //略
}

输出:16634

CopyOnWriteArrayList

线程安全

public class Main{
    private static List<Integer> list = new CopyOnWriteArrayList<>();
    //略
}

输出:20000

效率

public class Main{
    private static ArrayList<Integer> arrayList = new ArrayList<>();
    private static LinkedList<Integer> linkedList = new LinkedList<>();
    public static void main(String[] args){
        //插入
        System.out.println("插入在最后面");
        long s = System.currentTimeMillis();
        for (int i = 0; i < 100000; i++){
            arrayList.add(i);
        }
        System.out.println("10w次插入 arrayList:" + (System.currentTimeMillis() - s) + "ms");
        long s1 = System.currentTimeMillis();
        for (int i = 0; i < 100000; i++){
            linkedList.add(i);
        }
        System.out.println("10w次插入 linkedList:" + (System.currentTimeMillis() - s1) + "ms");

        //插入
        System.out.println("插入在最前面");
        long s2 = System.currentTimeMillis();
        for (int i = 0; i < 100000; i++){
            arrayList.add(0, i);
        }
        System.out.println("10w次插入 arrayList:" + (System.currentTimeMillis() - s2) + "ms");
        long s3 = System.currentTimeMillis();
        for (int i = 0; i < 100000; i++){
            linkedList.add(0, i);
        }
        System.out.println("10w次插入 linkedList:" + (System.currentTimeMillis() - s3) + "ms");

        //查找
        System.out.println("查找中间");
        long s4 = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++){
            arrayList.get(50000);
        }
        System.out.println("10w次查找 arrayList:" + (System.currentTimeMillis() - s4) + "ms");
        long s5 = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++){
            linkedList.get(99999);
        }
        System.out.println("10w次查找 linkedList:" + (System.currentTimeMillis() - s5) + "ms");
    }
}


输出:
插入在最后面
10w次插入 arrayList:5ms
10w次插入 linkedList:5ms
插入在最前面
10w次插入 arrayList:1994ms
10w次插入 linkedList:5ms
查找中间
10w次查找 arrayList:0ms
10w次查找 linkedList:1428ms
上一篇下一篇

猜你喜欢

热点阅读