Java复习知识点十八:List集合、ArrayList扩容机制、Vector、LinkedList的原理

1、List接口

基本介绍:List接口是Collection接口的子接口 单列集合

  1. List集合类中元素有序(即添加和取出顺序一致)、且可以重复

  2. List集合中的每个元素都有其对应的顺序索引,即支持索引

  3. List的所有实现子类:

    在这里插入图片描述

  4. 常用的只有 ArrayList、LinkedList、Vector

1.1 List接口常用方法

> List集合里添加了一些根据索引来操作集合元素的方法
  1. void add(int index.Object ele):在index位者插入ele元素

  2. boolean addAll(int index, Collection eles):从index位置开始将
    eles中的所有元素添加进来

  3. Object get(int index):获取指定index位置的元素

  4. int indexof(Object obj):返回obj在集合中首次出现的位置

  5. int lastIndexOf(Object obj):返向obj在当前集合中末次出现的位置

  6. Object remove(int index):移除指定index位置的元素,并返回此元

  7. Object set(int index,Object ele):设置指定index位智的元素为ele ,
    相当于是替换.

  8. List subList(int fromlndex, int tolndex):返回从fromlndex到
    tolndex位置的子集合

1.2 List的三种遍历方式

  1. 使用Iterator

    iterator = list.iterator();
    while (iterator.hasNext()) {
        System.out.print(iterator.next()+" ");
    }
    
  2. 使用增强for

    for (Object o : list) {
    	System.out.println(o);
    }
    
  3. 使用普通for

    for(int i = 0; i < list.size(); i++){
    	Object obj = list.get(i);
    	System.out.println(obj);
    }
    

2、ArrayList

2.1 ArrayList注意事项

  1. 可以存放任意值,包含null,ArrayList可以加入null,并且多个
  2. ArrayList是由数组实现数据存储
  3. ArrayList基本等同于Vector,除了ArrayList是线程不安全(执行效率高),在多线程情况下不建议使用ArrayList

2.2 ArrayLIst扩容源码分析

  1. ArrayList类中拥有一个 transient Object[ ] elementData成员变量,对象数组

     > transient表示该属性不会被序列化
    
  2. 使用无参构造器,创建ArrayList对象时,则初始elementData容量为0,第一次添加,则扩容elememtData为10,如果需要再次扩容,则扩容elementData为1.5倍

  3. 如果使用指定大小的构造器,则初始elementData容量为 指定大小,若需要扩容,则直接扩容为elementData的1.5倍

无参构造器:初始容量为空

在这里插入图片描述
在这里插入图片描述

添加第一个元素:会执行扩容到10

在这里插入图片描述

扩容方法:

在这里插入图片描述

有参构造:

在这里插入图片描述

3、Vector

3.1 Vector基本介绍

  1. Vector类的定义:

    在这里插入图片描述

  2. Vector底层也是一个对象数组,protected Object[] elementData;

  3. Vector是一个线程同步的,即线程安全,方法都带有synchronize

  4. 在开发中,需要线程同步安全时,考虑使用Vector

3.2 Vector扩容源码分析

  1. 使用无参构造器,会初始化容量为10,容量满后,会按照2倍扩容
  2. 使用有参构造,每次容量满后,直接按2倍扩容

无参构造:

在这里插入图片描述

调用有参构造:初始化大小为10

在这里插入图片描述

添加元素:

在这里插入图片描述

3.3 Vector vs ArrayList

在这里插入图片描述

4、LinkedList

4.1 LinkedList基本介绍

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

底层结构:

  1. LinkedList 底层维护了一个双向链表
  2. LinkedList 维护了两个属性 firstlast 分别指向 首节点尾结点
  3. 每个节点(Node对象),里面又维护了 prevnextitem三个属性,其中通过prev指向前一个,通过next指向后一个节点。最终实现双向链表。
  4. LinkedList 元素的添加和删除 不是通过 数组来完成的,相对来说效率较高

模拟一个双向链表:

public class LinkedList01 {
    public static void main(String[] args) {
        //模拟一个简单的双向链表

        Node jack = new Node("jack");
        Node tom = new Node("tom");
        Node bob = new Node("bob");

        //连接三个节点,形成双向链表
        //jack -> tom -> bob
        jack.next = tom;
        tom.next = bob;
        //bob -> tom -> jack
        bob.prev = tom;
        tom.prev = jack;

        Node first = jack;
        Node last = bob;

        //遍历 从头到尾
        System.out.println("====从头到尾=====");
        while (true) {
            if (first == null) {
                break;
            }
            System.out.println(first);
            first = first.next;

        }
        //遍历 尾到头
        System.out.println("=====从尾到头=====");
        while (true) {
            if (last == null) {
                break;
            }
            System.out.println(last);
            last = last.prev;

        }
        //添加节点 在 tom 和 bob之间
        Node simth = new Node("simth");
        simth.next = bob;
        simth.prev = tom;

        tom.next = simth;
        bob.prev = simth;
        //遍历
        System.out.println("=====添加元素后遍历=====");
        //让first再指向jack
        first = jack;

        while (true) {
            if (first == null) {
                break;
            }
            System.out.println(first);
            first = first.next;
        }
    }
}

//定义一个Node类,Node对象 表示 双向链表的一个节点
class Node {
    public Object item;//真正存放数据
    public Node next;//指向下一个节点
    public Node prev;//指向上一个节点

    public Node(Object name) {
        this.item = name;
    }
    
    @Override
    public String toString() {
        return "Node name=" + item;

    }
}

4.2 LinkedList源码分析

a> add添加方法流程

LinkedList linkedList =new LinkedList();

1、无参构造:

在这里插入图片描述

2、add方法:
linkedList.add(1)
在这里插入图片描述

3、进入linkLast方法:

在这里插入图片描述

​ 其中会创建内部类Node:

在这里插入图片描述

b> remove删除方法流程

remove()方法:会删除第一个元素

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

c> get查找方法流程

get(int index);方法
先判断索引是否存在
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

判断存在后返回执行查找方法get:

在这里插入图片描述

二分法进行循环查询

在这里插入图片描述

4.3 遍历方式

> 三种遍历方式都可

5、List集合的选择

5.1 ArrayList vs LinkedList

在这里插入图片描述

如何选择:

  1. 如果我们修改查询比较多,选择ArrayList
  2. 如果我们增删操作多,选择LinkedList
  3. 一般来说,在程序中,80%~90%都是查询,因此大部分情况下会选择ArrayList
  4. 在一个项目中,根据业务灵活选择,也可能这样,一个模块使用的是ArrayList,另一个模块是LinkedList
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值