Java学习 Day31_ArrayList

1.3 SubList: 切割List

在这里插入图片描述
视图:
SubList是一个视图方法
SubList: 切割方法, 它并没有真正的切割出数据, 仅仅是, 维护了源数据的一些标记, 标记那些元素是切割出来范围, 看上去好像是复制了一份数据(实际上并没有), 它里面的数据还是源数据
如果你修改切割出来的数据,会反应在源数据上

视图, 数据库. “虚表”: 给原本的数据划分不同表, 不同的表持有不同数据引用
比如一个商品在不同分类的数据库中,要修改价格,不可能将所有数据库中它的内容都修改一份,而是尽量只做一次修改


为什么Collection当中定义了这么多的抽象接口?
因为各个实现类会有重合的方法,不希望都去重复定义这个方法,所以把一部分放在一个抽象类当中,需要实现的类就去继承它

ArrayList

2.1 特点

1, ArrayList是List接口的子实现
2, 表示一个线性表
3, 底层结构是数组
4, 默认初始长度 10, 扩容机制1.5倍
5, 有序
6, 允许重复元素存储
7, 允许存储null
8, 线程不安全的

注意: 默认的构造ArrayList的时候, 构造方法只把这个底层数组, 变成一个空数组, 在第一次添加的时候, 才把数组变成长度为10

2.2 构造方法

在这里插入图片描述

2.3 API

api很多,大部分没有用,看文档吧,懒得截图了


2.4 clone()方法

复制一个浅表副本

在这里插入图片描述

clone方法复制了一个ArrayList的对象,这个新的对象里也有一个引用指向一个新的引用类型的数组,但每个引用指向的是原本的数据,也就是说ArrayList本身实现的是深拷贝(因为它不仅cloneArrayList对象本身,也clone了底层自己的数组)

=======================================

如果储存的元素不是String类型,而是一个类的对象呢?
不会重新创建新的对象,所有的引用都会指向原先的对象,如果要实现真正的深度拷贝,你必须将你储存的对象的类当中重写clone方法(也就是说ArrayList虽然实现了自己的深度拷贝,但是它存的对象本身可能并不支持深度拷贝)

ArrayList<String> list = new ArrayList<>();

        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        list.add("ddd");

        ArrayList<String> clone = (ArrayList<String>) list.clone();

        //只是修改了引用的指向,没有更改原来对象的内容,所以list打印出来的东西不变
        clone.set(0, "ZZZ");

        System.out.println(list); // aaa bbb ccc ddd
        System.out.println(clone); // ZZZ bbb ccc ddd

public class Demo {
    public static void main(String[] args) {
        
        ArrayList<Node> list2 = new ArrayList<>();

        list2.add(new Node("a"));
        list2.add(new Node("b"));
        list2.add(new Node("c"));


        // 并不能把上面添加的第一个元素删掉,因为remove中调用的是equals来比较,上面添加的和下面删除的不是同一个对象
        // 如果要实现这种删除,要在Node中重写equals方法
        list2.remove(new Node("a"));

        ArrayList<Node> clone = (ArrayList<Node>) list2.clone();

        // clone中修改会反映到原对象中,但是如果移除一个元素,但是原来的对象还存在,不会影响到list2
        clone.remove(0);
        
        // 这里修改,直接导致list2中的第二个元素中b变成Z
        clone.get(0).value = "Z";

        System.out.println(list2);
    }

}

class Node{
    String value;

    public Node(String value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return "Node{" +
                "value='" + value + '\'' +
                '}';
    }

    @Override
    public boolean equals(Object obj) {
        return value == ((Node)obj).value;
    }
}

在这里插入图片描述


Vector

3.1 特点

1, Vector是List接口的一个子实现 (List: jdk1.2 Vector: JDK1.0)
2, 描述的数据结构是线性表
3, 底层结构是数组
4, 底层的默认的初始长度 10 , 数组扩容机制, (如果增量大于0 ,扩增量个, 如果增量小于等于0扩为原来的2倍)
5, 有序
6, 允许重复
7, 允许存储null
8, Vector线程安全的

3.2 构造方法

在这里插入图片描述

Stack

4.1 特点

1, Stack 是Vector的一个子类(Stack 想复用Vector的底层结构, 参数,变量以及方法)
2, 描述的数据结构是栈
3, 底层结构是数组
4, 默认初始容量 10, 默认扩容机制是2倍
5, 有序, 允许重复, 允许null
6, 线程安全

如果使用Stack的时候, 尽量不要使用它从Vector继承来的方法 (因为既然使用了Stack, 那么你就是希望它作为栈而存储, 而非普通线性表)

如果我们真的需要一个栈, 可以优先用Deque接口下的具体实现 (因为Deque这个接口定义了栈的数据结构操作 )

LinkedList

5.1 特点

1, LinkedList 是 List 一个具体实现(同时它还实现了Deque接口)
2, 它所描述的数据结构: 线性表, 队列, 双端队列, 栈
3, 底层结构是一个双向链表
4, 有序
5, 允许存储重复元素
6, 允许存储null
7, 线程不安全

Deque这个接口: 描述的数据结构: 队列, 双端队列 , 栈

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值