JavaList源码解读(ArrayListLinkedListVector)

集合架构*

注明:根据韩顺平老师做的笔记

大致分为两类

单列集合

在这里插入图片描述

双列集合

在这里插入图片描述

在这里插入图片描述

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

package com.company.Collection;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class javasourcedemo1 {

    public static void main(String[] args) {
        Collection col = new ArrayList();
        col.add(new book("三国演义1","罗贯中1",30.11));
        col.add(new book("三国演义2","罗贯中2",30.12));
        col.add(new book("三国演义3","罗贯中3",30.13));


        System.out.println("col"+col);
    }
}
class book{
    private String name;
    private String author;
    private double price;
    public book(String name,String author,double price){
        this.name =name;
        this.author = author;
        this.price = price;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }package com.company.Collection;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class javasourcedemo1 {

    public static void main(String[] args) {
        Collection col = new ArrayList();
        col.add(new book("三国演义1","罗贯中1",30.11));
        col.add(new book("三国演义2","罗贯中2",30.12));
        col.add(new book("三国演义3","罗贯中3",30.13));

        Iterator iterator = col.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
        System.out.println("col"+col);
    }
}
class book{
    private String name;
    private String author;
    private double price;
    public book(String name,String author,double price){
        this.name =name;
        this.author = author;
        this.price = price;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getAuthor() {
        return author;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public double getPrice() {
        return price;
    }

    @Override
    public String toString() {
        return "book{" +
                "name='" + name + '\'' +
                ", author='" + author + '\'' +
                ", price=" + price +
                '}';
    }

    public book(){}
}

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getAuthor() {
        return author;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public double getPrice() {
        return price;
    }

    @Override
    public String toString() {
        return "book{" +
                "name='" + name + '\'' +
                ", author='" + author + '\'' +
                ", price=" + price +
                '}';
    }

    public book(){}
}
Collection 接口遍历
方式一 使用iterator (迭代器)

在这里插入图片描述

在这里插入图片描述

2)

遍历的三个过程

1、下移

2、将下移以后的集合位置元素返回

3、当遍历结束后 iterator迭代器 游标指向最后的元素

4、如果希望再次遍历 需要重置我们的迭代器

idea快捷键生成while ==》 itit
查找生成快捷键 ctrl+j
方式二增强for循环

1、使用增强for 在collection集合中

2、增强for 底层仍然事迭代器

3、增强for可以理解成就是简化版的迭代器遍历

4、快捷键方式

方式三使用普通的for
for (int i = 0;i<list.size();i++){
    
    System.out.println("list="+list.get(i));
}

//java测试

package com.company.Collection;
import com.company.Collection.javasourcedemo1;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class dogfor {
    public static void main(String[] args) {
        Collection list= new ArrayList();
        list.add(new dog("张",20));
        list.add(new dog("佳",20));
        list.add(new dog("琦",20));
        Iterator iterator = list.iterator();

        //使用for增强
        for (Object dog:list){
            System.out.println("dog:"+dog);
        }
        while (iterator.hasNext()) {
            System.out.println("iterator:"+iterator.next());
        }
    }
}
class dog{
    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public dog(String name,int age){
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
        return "dog{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

一、list(Vector|Arraylist |Linkedlist)

1、list接口和常用方法

List接口基本介绍

list接口时Collection接口的子接口 list.java

1)list集合接口中元素有序就是添加顺序和取出顺序一致 可重复

2)list集合中每个元素都有其对应的顺应索引 支持其索引

3)list容器中元素都对应一个整数型的序号记载其在容器中的位置 可以根据序号存取容器中的元素

4)jdk API 中实现的list接口实现类有:

​ Vector|Arraylist |Linkedlist

在这里插入图片描述

1.1、存取顺序一致可重复
package com.company.Collection;

import java.util.ArrayList;
import java.util.List;

public class listdemo1 {
    public static void main(String[] args) {
        //1)list集合接口中元素有序就是添加顺序和取出顺序一致 可重复
        List list = new ArrayList<>();
        list.add("张");
        list.add("佳");
        list.add("琦");
        list.add("孙");
        list.add("张");
        list.add("佳");
        list.add("琦");
        list.add("孙");
        System.out.println("list="+list);
}
}
1.2支持其索引
//list集合中每个元素都有其对应的顺应索引  支持其索引

System.out.println(list.get(3));
1.3数型的序号记载其在容器中的位置 可以根据序号存取容器中的元
//list集合中每个元素都有其对应的顺应索引  支持其索引

System.out.println(list.get(3));
1.4list接口的常用方法

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在集合中首次出现的位置,当所搜内容不存在时 就会返回-1

5、int lastIndexOf(Object obj):返回obj在集合中末次出现的位置,当所搜内容不存在时 就会返回-1

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

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

index 索引是必须要存在的 放在最后一个没有也是不可以 必须得存在位置

8、List subList(int fromIndex, int toIndex):返回从fromIndex 到toIndex位置的子集合
//[0,2) 左闭右开集合

public class ListMethod_ {
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add("宝宝");
        list.add("憨批");
        //1、void add(int index,Object ele) 在index位置插入ele元素
        //在索引为一的位置插入一个字符串对象
        list.add(1,"zjq");
        System.out.println("list="+list);
        //2、boolean addAll(int index, Collection eles):从index位置将eles中所有元素添加进来
        List listappend = new ArrayList();
        listappend.add("宝儿");
        listappend.add("猪");
        list.addAll(1,listappend);
        System.out.println("list="+list);
        //3、Object get(int index) :获取指定的index位置元素
        //说过
        //4、int indexOf(Object obj):返回obj在集合中首次出现的位置,当所搜内容不存在时 就会返回-1
        System.out.println(list.indexOf("猪"));
        //5、int lastIndexOf(Object obj):返回obj在集合中末次出现的位置,当所搜内容不存在时 就会返回-1
        list.addAll(list);
        System.out.println(list.lastIndexOf("zjq"));
        //6、object remove(int index):移除指定index 位置的元素  并返回此元素、
        System.out.println(list);
        list.remove(3);
        System.out.println(list);
        //7、Object set(int index, Object ele):设置指定index位置的元素ele,相当于替换
        //index 索引是必须要存在的  放在最后一个没有也是不可以  必须得存在位置
        list.set(1,"张佳琦");
        System.out.println(list);
        //8、List subList(int fromIndex, int toIndex):返回从fromIndex 到toIndex位置的子集合
        //[0,2) 左闭右开集合
        List list1 = list.subList(0,2);
        System.out.println(list1);
    }
}

二、ArrayList底层结构和源码分析

ArrayListDetail.java

1)permits all elements,including null,ArrayList 可以加入null 并且多个

public static void main(String[] args) {
    ArrayList arrayList = new ArrayList();
    int[] arr = {2,4,5,6,10};
    arrayList.add(null);
    arrayList.add("jack");
    arrayList.add(null);
    for (int o:arr) {
        System.out.println(o);
    }
    System.out.println(arrayList);
}

2)ArrayList 是由数组来实现数据存储的

3)ArrayList 基本等同与Vector 除了ArrayList是线程不安全(执行效率高)在多线程的条件下不使用arrayList

ArrayList原因没有synchronized


public boolean add(E e) {
    ++this.modCount;
    this.add(e, this.elementData, this.size);
    return true;
}
private void add(E e, Object[] elementData, int s) {
    if (s == elementData.length) {
        elementData = this.grow();
    }

    elementData[s] = e;
    this.size = s + 1;
}
public void ensureCapacity(int minCapacity) {
    if (minCapacity > this.elementData.length && (this.elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA || minCapacity > 10)) {
        ++this.modCount;
        this.grow(minCapacity);
    }

}

Vector原因有synchronized就安全互斥

public synchronized boolean add(E e) {
    ++this.modCount;
    this.add(e, this.elementData, this.elementCount);
    return true;
}

ArrayList源码

transient瞬间,短暂的不会被序列化

capacity 是容量意思

explicit是否要移动

>> 右移 就是相当于除以2

debug时的数据都是阉割过的数据如果在debug中完全显示 将enavle alternative view for Collections classes 勾选给划掉

在这里插入图片描述

E是泛型类,可传入的是你要传入的参数类型 E e是泛型标识符

1)ArrayList 中维护一个Object类型的数组(elementData)[debug 看源码]

transient Object[] elementData;

2)当创建ArrayList 对象时 如果使用的时无参则初始的elementData容量为0,第一此添加 则扩容elementData 为10 如果再次扩容发 则扩容elementData1.5倍

无参构造 第一次 0——10 ——>15——15+15/2 ==22 ——>33…

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

无参构造扩容过程

在这里插入图片描述

在这里插入图片描述

有参构造扩容过程

在这里插入图片描述

三、Vector底层结构和源码剖析

Vector的基本介绍

1)vector类定义说明

在这里插入图片描述

2)Vector底层也是对象数组 protect Object[] elementData;

在这里插入图片描述

3)Vector 线程同步安全 ,vector类的操作方法带有synchronzed

底层结构版本线程安全效率扩容倍数
ArrayList可变数组jdk1.2不安全效率高无参:第一次10 从第二次1.5倍扩 有参1.5倍扩
Vector可变数组Object[]jdk1.0安全效率不高如果无参 默认10 满后按照2倍扩 如果是指定大小 则每次直接按2倍扩

四、linkedList底层结构

4.1 LinkedList全面说明

1)LinkedList底层实现了双向链表和双端队列特点

2)可以添加任意元素 元素可以重复 包括null

3)线程不安全,没有实现同步、

4.2 LinkedList的底层操作机制

1)LinkedList底层维护了一个双向链表

2)LinkedList中维护了两个属性first和last分别指向首节点 和尾节点

3)每个节点(node 对象)里面维护了prev、next、item三个属性 其中通过prev指向前一个通过next指向后一个最终实现双向链表

4)所以LinkedList的元素添加和删除不是通过数组完成的 相对来说效率高

5)模拟一个简单的双向链表

4.3增删查改案例

package com.company.Collection.list;

import java.util.LinkedList;

public class LinkedList_ {
    public static void main(String[] args) {
        LinkedList linkedList = new LinkedList();
        for (int i = 0; i < 2; i++) {
            linkedList.add(i);
        }
        linkedList.add(100);
        linkedList.add(100);
        for (Object object:linkedList) {
            System.out.println(object);
        }
        linkedList.set(0,"zjq");
        System.out.println("========");
        for (Object object:linkedList) {
            System.out.println(object);
        }
        Object object = linkedList.get(0);
        System.out.println("object="+object);
        System.out.println("first="+linkedList.getFirst());
        System.out.println("last="+linkedList.getLast());
    }
}

4.4源码解析

1、第一步
LinkedList linkedList = new LinkedList();
2、这是 linklist属性 first null,lastnull
3、执行 添加
public boolean add(E e) {
    linkLast(e);
    return true;
}
3.1、添加到双向链表的最后的
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++;
}
4、删除
4.1第一步
linkedList.removeFirst(1);
public E removeFirst() {
    final Node<E> f = first;
    if (f == null)
        throw new NoSuchElementException();
    return unlinkFirst(f);
}
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双向链表较高,通过链表追加较低

st(f);
}




```java
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双向链表较高,通过链表追加较低
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值