• ArrayList、LinkedList、Vector、Array


    ArrayList 本质是一个数组。

    优势:追加元素到数组末尾的时候速度快,同时检索元素的速度也快。

    劣势:如果要插入一个元素到数组之间慢;如果要追加的元素数量多于数组的容量,则需要频繁扩容使用Arrays.Arrays.copyOf 重新创建一个合适容量的数组

    LinkedList 本质是一个list

    优势:追加元素没有容量限制,追加速度快,无论是追加元素到链表哪个位置

    劣势:检索元素慢

    测试代码如下:

    package com.drafire.testall.Sevice;
    
    import org.junit.Ignore;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.LinkedList;
    import java.util.Random;
    
    @SpringBootTest
    @RunWith(SpringRunner.class)
    public class ListClass {
        private final ArrayList arrayList = new ArrayList();
        private final LinkedList linkedList = new LinkedList();
    
        //初始化容量
        private static int INITIAL_SIZE = 10000000;
        //累计插入元素的次数
        private static int ADD_SIZE = 1000;
        //插入的元素
        private static int ADD_NUM = 3;
        //插入元素的位置
        private static int ADD_INDEX = 988;
        //线程数量
        private static final int THREAD_SIZE = 10;
        //修改元素的位置
        private final int CHANGE_INDEX = 5;
    
        //测试线程安全
        @Test
        public void testThreadSafe() {
            init();
            testArrayListThreadSafe();
            testLinkedListThreadSafe();
        }
    
        //测试性能
        @Test
        public void testNature() {
            setArrayList();
            setLinkedList();
    
            testAddArrayList();
            testAddLinkList();
    
            testQueryArrayListItem();
            testQueryLinkedListItem();
        }
    
        private void init() {
            for (int i = 0; i < THREAD_SIZE; i++) {
                arrayList.add(i, THREAD_SIZE + i);
                linkedList.add(i, THREAD_SIZE + i);
            }
        }
    
        private void testArrayListThreadSafe() {
            MyArrayListThread[] myArrayListThreads = new MyArrayListThread[THREAD_SIZE];
            for (int i = 0; i < THREAD_SIZE; i++) {
                myArrayListThreads[i] = new MyArrayListThread(i);
            }
            for (int i = 0; i < THREAD_SIZE; i++) {
                Thread thread = new Thread(myArrayListThreads[i]);
                thread.start();
            }
            System.out.println("arrayList[" + CHANGE_INDEX + "]=" + arrayList.get(CHANGE_INDEX));
        }
    
        private void testLinkedListThreadSafe() {
            MyLinkedListThread[] myLinkedListThreads = new MyLinkedListThread[THREAD_SIZE];
            for (int i = 0; i < THREAD_SIZE; i++) {
                myLinkedListThreads[i] = new MyLinkedListThread(i);
            }
    
            for (int i = 0; i < THREAD_SIZE; i++) {
                //不要调用run方法。因为run()实际上只是跑了主进程一个线程
                Thread thread = new Thread(myLinkedListThreads[i]);
                thread.start();
            }
            System.out.println("linkedList[" + CHANGE_INDEX + "]=" + linkedList.get(CHANGE_INDEX));
        }
    
        private void setArrayList() {
            Date st = new Date();
            for (int i = 0; i < INITIAL_SIZE; i++) {
                arrayList.add(i);
            }
            Date et = new Date();
            System.out.println("arrayList 初始化使用时间:" + (et.getTime() - st.getTime()));
        }
    
        private void setLinkedList() {
            Date st = new Date();
            for (int i = 0; i < INITIAL_SIZE; i++) {
                linkedList.add(i);
            }
            Date et = new Date();
            System.out.println("linkedList 初始化使用时间:" + (et.getTime() - st.getTime()));
        }
    
        private void testAddArrayList() {
            //ArrayList 本质是一个数组。集合的优势在于,追加元素到数组末尾的时候速度快,同时检索元素的速度也快。
            // 但是如果要插入一个元素到数组之间,就慢;另外,如果要追加的元素数量多于数组的容量,则需要频繁扩容
            //使用Arrays.Arrays.copyOf 重新创建一个合适容量的数组
            Date st = new Date();
            for (int i = 0; i < ADD_SIZE; i++) {
                arrayList.add(ADD_INDEX, ADD_NUM);
            }
            Date et = new Date();
            System.out.println("arrayList在" + ADD_INDEX + "处添加元素:" + ADD_NUM + "," + ADD_SIZE + "次,使用时间:" + (et.getTime() - st.getTime()));
        }
    
        private void testAddLinkList() {
            //LinkedList本质是一个链表。list的优势在于,没有容量的概念,追加元素速度快
            Date st = new Date();
            for (int i = 0; i < ADD_SIZE; i++) {
                linkedList.add(ADD_INDEX, ADD_NUM);
            }
            Date et = new Date();
            System.out.println("linkedList在" + ADD_INDEX + "处添加元素:" + ADD_NUM + "," + ADD_SIZE + "次,使用时间:" + (et.getTime() - st.getTime()));
        }
    
        private void testQueryArrayListItem() {
            Date st = new Date();
            for (int i = 0; i < ADD_SIZE; i++) {
                arrayList.get(new Random().nextInt(INITIAL_SIZE));
            }
            Date et = new Date();
            System.out.println("arrayList随机检索元素:" + ADD_SIZE + "次,使用时间:" + (et.getTime() - st.getTime()));
        }
    
        private void testQueryLinkedListItem() {
            Date st = new Date();
            for (int i = 0; i < ADD_SIZE; i++) {
                linkedList.get(new Random().nextInt(INITIAL_SIZE));
            }
            Date et = new Date();
            System.out.println("linkedList随机检索元素:" + ADD_SIZE + "次,使用时间:" + (et.getTime() - st.getTime()));
    
        }
    
        private class MyArrayListThread implements Runnable {
    
            private int value;
    
            public MyArrayListThread(int v) {
                this.value = v;
            }
    
            @Override
            public void run() {
                arrayList.set(CHANGE_INDEX, value);
            }
        }
    
        private class MyLinkedListThread implements Runnable {
    
            private int value;
    
            public MyLinkedListThread(int v) {
                this.value = v;
            }
    
            @Override
            public void run() {
                linkedList.set(CHANGE_INDEX, value);
            }
        }
    }

    调用testNature(),结果如下:

    arrayList 初始化使用时间:4290
    linkedList 初始化使用时间:1676
    arrayList在988处添加元素:3,1000次,使用时间:6037
    linkedList在988处添加元素:3,1000次,使用时间:5
    arrayList随机检索元素:1000次,使用时间:7
    linkedList随机检索元素:1000次,使用时间:34017

    调用testThreadSafe(),结果如下:

    arrayList[5]=9
    linkedList[5]=8

    从上面结果可以看出,ArrayList 和LinkedList 都是非线程安全的

     ----------------------------------------------------------------------------------------------

    关于Vector,Vector的本质也是一个数组,数组的优劣势也是它的优劣势。

    看jdk 的源码,发现好多方法都是用synchronized修饰的,想当然,我们认为这个是线程安全的。看下面的测试代码:

    package com.drafire.testall.Sevice;
    
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    
    import java.util.Vector;
    
    @SpringBootTest
    @RunWith(SpringRunner.class)
    public class VectorClass {
        private final Vector vector = new Vector();
    
    
        //修改元素的位置
        private final int CHANGE_INDEX = 5;
        //线程数量
        private static final int THREAD_SIZE = 10;
        //测试线程安全
        @Test
        public void testThreadSafe() {
            for (int i = 0; i < THREAD_SIZE; i++) {
                vector.add(i, THREAD_SIZE + i);
            }
            MyVectorThread[] myVectorThreads = new MyVectorThread[THREAD_SIZE];
            for (int i = 0; i < THREAD_SIZE; i++) {
                myVectorThreads[i] = new MyVectorThread(i);
            }
            for (int i = 0; i < THREAD_SIZE; i++) {
                //不要调用run方法。因为run()实际上只是跑了主进程一个线程
                Thread thread = new Thread(myVectorThreads[i]);
                thread.start();
            }
            System.out.println("vector[" + CHANGE_INDEX + "]=" + vector.get(CHANGE_INDEX));
        }
    
        private class MyVectorThread implements Runnable {
            private int value;
            public MyVectorThread(int v) { this.value = v; }
            @Override
            public void run() { vector.set(CHANGE_INDEX, value); }
        }
    }

    多次测试,发现上面输出结果,并非都是我们想象中的:vector[5]=9。这是因为,线程安全,指的是单个操作安全,复合操作有问题(我也不懂什么叫复合操作)。

    -----------------------------------------------------------------------------------

    数组(Array)和列表(ArrayList)有什么区别

     Array可以包含基本类型和对象类型,ArrayList只能包含对象类型

    Array大小固定,ArrayList的大小是动态变化的。

    ArrayList提供了更多的方法和特性:比如 :addAll(),removeAll(),iterator()等等。

  • 相关阅读:
    hdu4276 依赖背包
    poj1155 依赖背包
    cf219d 基础换根法
    贪婪大陆——(树状数组)
    数星星(树状数组或者线段树)
    拓扑排序基础题——排序
    Codeforces Round #511 (Div. 1) T2 Little C Loves 3 II
    除虫药水(简单dp)
    烽火传递(单调队列优化dp,然而蒟蒻用一个优先队列做)
    ZOJ----3471Most powerful(简单状压dp)
  • 原文地址:https://www.cnblogs.com/drafire/p/10647115.html
Copyright © 2020-2023  润新知