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()等等。

ArrayList、LinkedList、Vector、Array的更多相关文章

  1. ArrayList、LinkedList和Vector的源码解析,带你走近List的世界

    java.util.List接口是Java Collections Framework的一个重要组成部分,List接口的架构图如下: 本文将通过剖析List接口的三个实现类——ArrayList.Li ...

  2. Java 容器 & 泛型:二、ArrayList 、LinkedList和Vector比较

    Writer:BYSocket(泥沙砖瓦浆木匠) 微博:BYSocket 豆瓣:BYSocket 继续上一篇的容器文章认识容器,泥瓦匠慢慢带你们走进List的容器解说.今天泥瓦匠想说说 ArrayLi ...

  3. Java集合(六)--ArrayList、LinkedList和Vector对比

    在前两篇博客,学习了ArrayList和LinkedList的源码,地址在这: Java集合(五)--LinkedList源码解读 Java集合(四)--基于JDK1.8的ArrayList源码解读 ...

  4. ArrayList、LinkedList和Vector源码分析

    ArrayList.LinkedList和Vector源码分析 ArrayList ArrayList是一个底层使用数组来存储对象,但不是线程安全的集合类 ArrayList的类结构关系 public ...

  5. ArrayList vs LinkedList vs Vector

    List概览 List,正如它的名字,表明其是有顺序的.当讨论List的时候,最好拿它跟Set作比较,Set中的元素是无序且唯一:下面是一张类层次结构图,从这张图中,我们可以大致了解java集合类的整 ...

  6. java集合【12】——— ArrayList,LinkedList,Vector的相同点与区别是什么?

    目录 特性列举 底层存储结构不同 线程安全性不同 默认的大小不同 扩容机制 迭代器 增删改查的效率 总结一下 要想回答这个问题,可以先把各种都讲特性,然后再从底层存储结构,线程安全,默认大小,扩容机制 ...

  7. 数组Array和列表集合ArrayList、LinkedList和Vector的区别

    一.ArrayList和Vector的区别 ArrayList与Vector主要从以下方面来说. 1.同步性: Vector是线程安全的,也就是说是同步的,而ArrayList是线程序不安全的,不是同 ...

  8. ArrayList和LinkedList和Vector源码分析

    ArrayList源码: private static final int DEFAULT_CAPACITY = 10;//默认长度 /** * Shared empty array instance ...

  9. ArrayList,LinkedList,Vector,Stack之间的区别

    一,线程安全性 Vector.Stack:线程安全 ArrayList.LinkedList:非线程安全 二,实现方式 LinkedList:双向链表 ArrayList,Vector,Stack:数 ...

  10. java的List接口的实现类 ArrayList,LinkedList,Vector 的区别

    Java的List接口有3个实现类,分别是ArrayList.LinkedList.Vector,他们用于存放多个元素,维护元素的次序,而且允许元素重复. 3个具体实现类的区别如下: 1. Array ...

随机推荐

  1. MySQL 学习笔记(一)MySQL 事务的ACID特性

    MySQL事务是什么,它就是一组数据库的操作,是访问数据库的程序单元,事务中可能包含一个或者多个 SQL 语句.这些SQL 语句要么都执行.要么都不执行.我们知道,在MySQL 中,有不同的存储引擎, ...

  2. 2020CCPC长春F. Strange Memory

    题目大意 一棵以 \(1\) 为根的 \(n(2\leq n\leq 10^5)\) 的树,每个节点 \(i\) 有权值 \(a_{i}(1\leq a_{i}\leq 10^6)\) ,求 \(\s ...

  3. 哈工大 计算机系统 实验七 TinyShell

    所有实验文件可见github 计算机系统实验整理 实验报告 实 验(七) 题 目 TinyShell 微壳 计算机科学与技术学院 目 录 第1章 实验基本信息 - 4 - 1.1 实验目的 - 4 - ...

  4. Pycharm:Python2和3及其的Anaconda的正确设置

    这两天学习需要用到第三方库pyKriging,然而电脑之前下载的是Python2.7,pyKriging只支持Python3.6,尝试了很多方法也无果后,只好重新下载Python3.6,由于在网上查到 ...

  5. python刷剑指offer(1-20)(一刷)

    2019/07/28开始刷每天6题,一共66题,刷三遍,9月1号完成. 1.二维数组中的查找: 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增 ...

  6. k8s集群StatefulSets的Pod优雅调度问题思考?

    k8s集群StatefulSets的Pod优雅调度问题思考 考点之你能解释一下为什么k8s的 StatefulSets 需要VolumeClaimTemplate嘛? 考点之简单描述一下Statefu ...

  7. 面试官:我们来聊一聊Redis吧,你了解多少就答多少

    哈喽!大家好,我是小奇,一位不靠谱的程序员 小奇打算以轻松幽默的对话方式来分享一些技术,如果你觉得通过小奇的文章学到了东西,那就给小奇一个赞吧 文章持续更新,建议收藏关注 一.前言 作为一名Java程 ...

  8. 【SpringMVC从入门到精通】00-SpringMVC 简介

    笔记来源:[尚硅谷]SpringMVC教程丨一套快速上手spring mvc 目录 SpringMVC 简介 1.课程介绍 2.什么是 MVC? 3.什么是 SpringMVC? 4.SpringMV ...

  9. centos7 安装 nginx-1.18.0 并设置开机自启动

    一.到官网下载nginx Mainline  version:  nginx主力版本,为开发版 Stable version: 稳定版,在生产环境中选择此版本进行安装 Legacy versions: ...

  10. Casbin入选2022 Google编程之夏

    Casbin入选2022 Google编程之夏! Google编程之夏(Google Summer of Code,GSoC),是由Google公司所主办的年度开源程序设计项目,第一届从2005年开始 ...