IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> List接口实现:ArrayList、LinkedList、Vector -> 正文阅读

[数据结构与算法]List接口实现:ArrayList、LinkedList、Vector

List

List 介绍

list集合每个元素都对应索引,索引从0开始
list集合中元素有序(添加和取出顺序一致),可重复

常用方法

 get 获取
 set 修改
 indexOf 返回在集合中首次出现的位置
 lastIndexOf 返回在集合中最后一次出现的位置
 subList 返回从fromIndex到toIndex位置的子集合,包括前面

List接口练习

 使用 list接口实现类添加三本书,并遍历
 要求:
       1.按价格排序,从低到高(冒泡排序)
 
public class list接口练习 {
    public static void main(String[] args) {

        List list = new ArrayList();

        list.add(new Book("三国演义","罗贯中",50.0));
        list.add(new Book("红楼梦","曹雪芹",100.0));
        list.add(new Book("西游记","吴承恩",30.0));
        list.add(new Book("水浒传","施耐庵",60.0));

        for (Object o : list) {
            System.out.println(o);
        }

        System.out.println("----------------排序后");
        for (Object o : list) {
            System.out.println(o);
        }
    }

    //冒泡排序,从低到高
    public static void sort(List list){
        int size = list.size();
        for (int i = 0; i <size -1; i++) {
            for (int j = 0; j < size -i -1; j++) {
                Book book = (Book) list.get(j);
                Book book1 =(Book) list.get(j + 1);
                if (book.getPrice() > book1.getPrice()){
                    list.set(j,book1);
                    list.set(j+1,book);
                }
            }
        }
    }
}
class Book {...}

ArrayList

1.ArrayList是由 数组 来实现数据存储的
2.ArrayList等同于Vector,ArrayList是线程不安全(执行效率高);在多线程情况下,不建议使用ArrayList

ArrayList 底层机制 和 源码分析

1.ArrayList中维护了一个Object类型的数组 elementData
2.当创建ArrayList对象时,如果使用的是无参构造器,则初始elementData的容量为0,第一次添加则扩容elementData为10,如需要再次扩容,则扩容elementData的1.5倍
3.如果使用的是指定大小的构造器,则初始elementData容量为指定大小,如果需要扩容,则直接扩容elementData的1.5倍

扩容机制 流程图示
在这里插入图片描述

ArrayList add() 扩容机制:如果 需要的最小容量 比 默认容量大,执行grow(int minCapacity)方法扩容

//1 走 ensureCapacityInternal()方法 确认内部容量,此时size默认为0,初始容量elementData默认为0
public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // minCapacity= size + 1 = 1
    elementData[size++] = e;
    return true;
}

//2 先走 calculateCapacity()方法 计算容量,此时初始容量elementData默认为0,需要的最小容量minCapacity为1
private void ensureCapacityInternal(int minCapacity) {
    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}

//3 走calculateCapacity()方法,DEFAULTCAPACITY_EMPTY_ELEMENTDATA默认为0,DEFAULT_CAPACITY默认容量为10
//  if判断:初始容量elementData为0,则返回DEFAULT_CAPACITY=10
private static int calculateCapacity(Object[] elementData, int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        return Math.max(DEFAULT_CAPACITY, minCapacity);
    }
    return minCapacity;
}

//4 走ensureExplicitCapacity() 判断是否需要扩容,此时需要的最小容量minCapacity=10,如果需要的最小容量比初始容量elementData要大,执行grow()扩容
private void ensureExplicitCapacity(int minCapacity) {
    modCount++;
    // overflow-conscious code
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}

//5 走grow()扩容方法,传入需要的最小容量10,这里初始elementData为0,所以newCapcity还为10
//  如果elementData里面有值,则按elementData的1.5倍进行扩容
private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
    // minCapacity is usually close to size, so this is a win:
    elementData = Arrays.copyOf(elementData, newCapacity);
}

最后返回到add方法,把add的值添加进行数组

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HqKb7KAP-1634200934864)(src/image/ArrayList add()].png)

ArrayList源码总结

1.创建无参构造方法时,数组的容量elementData默认为0
2.如果 需要的最小容量(minCapacity)比 默认容量(elementData) 大,则进行扩容操作

Vector

1.Vector底层也是一个对象数组,protected Object[] elementData;
2.Vector是线程同步的,即线程安全,Vector类的操作方法带有 synchronized
3.需要线程同步安全时,需要考虑使用Vector

Vector和ArrayList比较

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZSoMVSCB-1634200934865)(src/image/Vector和ArrayList比较.png)]

Vector 源码解析

无参构造器vector初始化后,初始容量为10,后面按2倍扩容

// 1.不传参数,默认走Vector的无参构造器,初始容量给 10
public Vector() {
    this(10);
}
// 2
public Vector(int initialCapacity) {
    this(initialCapacity, 0);
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oBJX2XTN-1634200934865)(src/image/vector初始化.png)]

Vector 扩容机制

// 1 判断扩容方法 ensureCapacityHelper(最小容量) 

public synchronized boolean add(E e) {
    modCount++;
    ensureCapacityHelper(elementCount + 1);
    elementData[elementCount++] = e;
    return true;
}

// 2 判断条件:当 需要的最小容量比数组容量大时,执行grow()方法扩容,

private void ensureCapacityHelper(int minCapacity) {
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}

// 3 grow()方法,扩容到2倍

private void grow(int minCapacity) {
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                     capacityIncrement : oldCapacity);
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
    elementData = Arrays.copyOf(elementData, newCapacity);
}


LinkedList

1.LinkedList 底层实现了( 双向链表 + 双端队列 )
2.可以添加任意元素(元素可以重复),包括null
3.线程不安全,没有实现同步

LinkedList 底层结构

1.LinkedList 底层维护了一个双向链表
2.LinkedList中维护了两个属性 first 和 last 分别指向首节点和尾节点
3.每个节点(Node对象),里面又维护了prev、next、item三个属性,通过prev指向前一个,通过next指向后一个,实现双向链表
4.所以LinkedList的元素增加和删除,相较于效率较高

双向链表图示

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ftgInbJg-1634200934866)(src/image/双向链表.png)]

LinkedList 源码解析

LinkedList 创建无参构造器过程;此时,size为0,first、last为Null


//1 走LinkedList的无参构造器 初始化 size=0
    public LinkedList() {}
    
//  transient int size = 0;
    

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vGNcDGJ3-1634200934867)(src/image/LinkedList创建无参构造器过程.png)]

LinkedList 扩容机制

linkedList.add(12);

//1 走 linkLast(e)方法
    public boolean add(E e) {
        linkLast(e);
        return true;
    }

//2 第一次添加: last=null,l也为null,此时first、last都指向新节点
    多次添加:last不为null,此时新节点的prev指向最后节点,最后节点的next指向新节点
    
    void linkLast(E e) {
        final Node<E> l = last;
        final Node<E> newNode = new Node<>(l, e, null);
        last = newNode;
        if (l == null)
            first = newNode;
        else
            l.next = newNode;
        size++;
        modCount++;
    }

remove()方法,默认删除首节点

//1 走 removeFirst()方法
public E remove() {
    return removeFirst();
}

//2 第一个节点不为null,执行unlinkFirst(f)方法,删除第一个节点
public E removeFirst() {
    final Node<E> f = first;
    if (f == null)
        throw new NoSuchElementException();
    return unlinkFirst(f);
}

//3 unlinkFirst() 删除首节点f,先把f的值赋给element,再把f.next赋给一个新next节点,把f的值和next赋为空,
//此时first.next指向新next节点,再把next的prev赋为空,该操作就是把first指向首节点的next,再把首节点的prev赋为空

private E unlinkFirst(Node<E> f) {
    // assert f == first && f != null;
    final E element = f.item;
    final Node<E> next = f.next;
    f.item = null;
    f.next = null; // help GC
    first = next;
    if (next == null)
        last = null;
    else
        next.prev = null;
    size--;
    modCount++;
    return element;
}

ArrayList 和 LinkedList 比较

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VDjGx4hn-1634200934867)(src/image/ArrayList和LinkedList比较.png)]

如何选择?

1.如果改查多,选择ArrayList
2.如果增删多,选择LinkedList
3.一般大部分都是改查,大部分情况都会选ArrayList
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-10-15 12:02:00  更:2021-10-15 12:03:46 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 7:51:15-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码