ArrayList 和 LinkedList

 集合框架的意义

        对于一般的数组,是定长的线性存储结构,所以对于数据量不确定的对象,使用数组存储就不再适用了,集合框架就是对此提出的解决方案

        从上图我们可以知道,Java集合框架类型分为两大类:Collection 和 Map,这一章我们主要简单了解一下 Collection 及其子类

        Collection 接口存储对象可以是不唯一的,无序的

        List 接口存储的对象可以是不唯一的,但是有序的

        Set 接口存储对象是唯一且无序的

        Map 接口存储对象以键值对的形式存在,提供 key 到 value 的映射

ArrayList

       List 接口继承自 Collection 接口,常涉及的子类包括:ArrayList、LinkedList,两者最大的区别在于实现方式:前者采用数组

       ArrayList 实现了长度可变的数组,在内存中分配连续的空间,因此遍历元素和随机访问元素的效率较高

       常用方法如下

        用法举例如下

public class TestArrayList {
    public static void main(String[] args) {
        // 当未使用泛型时,可以混合存储数据或对象
        ArrayList numList = new ArrayList();

        // 若不指定存储位置,默认在集合结尾处添加
        numList.add(1);
        numList.add("2");
        numList.add(3.0);

        // 指定位置,数据插入,而非覆盖
        numList.add(1, "666");

        // 查看元素,需向上转型
        Object o = numList.get(2);
        System.out.println(o);
        System.out.println(numList.get(1));

        // 计算大小
        System.out.println(numList.size());

        // 遍历集合
        for (int i = 0; i < numList.size(); i++) {
            System.out.print(numList.get(i) + " ");
        }
        System.out.println();

        // 增强for遍历
        for (Object num : numList) {
            System.out.print(num + " ");
        }
        System.out.println();

        // 查找
        System.out.println(numList.contains(777));



        // 当泛型确定类型时,不能容纳其他类型数据或对象
        ArrayList<Student> studentList = new ArrayList();

        // 当处理对象时
        studentList.add(new Student("tom"));
        studentList.add(new Student("jerry"));
        studentList.add(new Student("kitty"));
        Student tom = new Student("tom");
        // 注意比较存储对象和存储值的区别
        System.out.println(studentList.contains(tom));

        // 删除元素
        // 方法1:通过下标,返回对象
        System.out.println(studentList.remove(2));

        // 方法2:通过对象引用删除,该方法是无法删除的
        // 因为tom变量中保存的地址值,不在studentList里面
        System.out.println("remove:" + studentList.remove(tom));

        // 方法3:先查找到要删除的元素
        Student foundStudent = null;
        for (Object stuObj : studentList) {
            // 由于student对象保存到集合时,做了类型擦除(向上转型为Object)
            // 所以取出对象时,要做强转
            Student stu = (Student) stuObj;
            if ("tom".equals(stu.getName())) {
                foundStudent = stu;
                break;
            }
        }
        // 再进行删除
        if (foundStudent != null) {
            System.out.println("remove:" + studentList.remove(foundStudent));
        }
    }
}

 ArrayList扩容机制

        我们可以将 ArrayList 理解为可变长数组,这得益于其独有的扩容机制

        我们只需要知道 ArrayList 扩容机制为 1.5 ,我们来看看它的源码

private void grow(int minCapacity) {
    // overflow-conscious code
    // oldCapacity为旧容量,newCapacity为新容量
    int oldCapacity = elementData.length;

    // 将oldCapacity右移一位,其效果相当于oldCapacity/2
    // 再加上原值,即扩充了1.5倍
    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);
}

LinkedList

        LinkedList 实现方法不同于 ArrayList ,采用的是链表结构

        由于LinkedList由链表实现,LinkedList 提供对头部和尾部元素进行添加和删除操作的方法 ,也可以在集合任何位置(头部、中间、尾部)添加、获取、删除集合对象

        因此,插入、删除操作频繁时,可使用 LinkedList 来提高效率

        常用方法如下:

        使用方法两者别无二致,我们不再赘述

        用法举例如下

public class TestLinkedList {
    public static void main(String[] args) {
        LinkedList studentList = new LinkedList();
        studentList.addLast(new Student("tom1"));
        studentList.addLast(new Student("tom2"));
        studentList.addFirst(new Student("tom3"));

        System.out.println(studentList.getFirst());
        System.out.println(studentList.getLast());
        System.out.println(studentList.get(1));

        studentList.removeFirst();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值