21 JAVA API 4-1 集合 List ArrayList LinkedList

集合

我们接下来要学习的内容是Java基础中一个很重要的部分:集合

1 Collection接口

  1. Collection是集合层次中的根接口
  2. 集合的继承关系:常用的集合类有List集合,Set集合,Map集合,其中List集合与Set集合继承了Collection接口,各个接口还 提供了不同的实现类.
  3. 测试常用方法

1.1 前言

Java语言的java.util包中提供了一些集合类,这些集合类又称之为容器
提到容器不难想到数组,集合类与数组最主要的不同之处是,数组的长度是固定的,集合的长度是可变的,而数组的访问方式比较单一,插入/删除等操作比较繁琐,而集合的访问方式比较灵活
在这里插入图片描述
常用的集合类有List集合,Set集合,Map集合,其中List集合与Set集合继承了Collection接口,各个接口还提供了不同的实现类.
在这里插入图片描述

1.2 集合概念

集合的英文名称是Collection,是用来存放对象的数据结构,而且长度可变,可以存放不同类型的对象,并且还提供了一组操作成批对象的方法.Collection接口层次结构 中的根接口,接口不能直接使用,但是该接口提供了添加元素/删除元素/管理元素的父接口公共方法.
由于List接口与Set接口都继承了Collection接口,因此这些方法对于List集合和Set集合是通用的.

1.3 集合的继承结构

Collection接口
List 接口【数据有下标,有序,可重复】

ArrayList子类
LinkedList子类

Set 接口【数据无下标,无序,不可重复】

HashSet子类

Map 接口【键值对的方式存数据】

HashMap子类

1.4 Collection方法速查表

在这里插入图片描述

1.5 迭代

  1. 获取集合的迭代器 c2.iterator
  2. 利用迭代器进行判断,当前集合中是否有下一个可迭代的元素 it.hasNext()
  3. 利用迭代器获取当前迭代的元素 ii.next()

1.6 练习:Collection接口测试

package cn.collection;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;

/* 本类用于测试collection接口中的常用方法*/
public class TestCollection {
    public static void main(String[] args) {
        //1.创建Collection相关的对象
        //Collection c = new Collection(); //报错,因为collection是接口
        Collection<Integer> c = new ArrayList();
        Collection<Integer> c1 = new ArrayList<Integer>(); //俩种写法均可,功能一致
        Collection<Integer> c2 = new ArrayList();
        Collection c5 = new ArrayList<Integer>(); //不能写到后边,写到后边约束不了类型,不起作用
        c.add(100);
        c.add(200);
        c.add(300);
        c.add(400);
        c.add(500);
        System.out.println(c);

    c2.add(2);
    c2.add(4);
    c2.add(6);
    c2.add(8);

        //3.测试集合中的常用方法
        System.out.println(c.hashCode()); //获取集合对象对应的哈希码值
        System.out.println(c.toString()); //[100, 200, 300, 400, 500]
        System.out.println(c.equals(200)); //false 比较集合对象与值200是否相等

        System.out.println(c.contains(200)); //true,集合中是否包含指定元素200
        System.out.println(c.isEmpty());  //false,判断集合是否为空
        System.out.println(c.remove(100)); //true,移除集合中的指定元素,成功返回true
        System.out.println(c.toString());//[200, 300, 400, 500]

        System.out.println(c.size());//4,返回集合的元素个数

        Object[] array = c.toArray();//将指定的集合转为数组Object[]
        // 输入c.toArray();,使用alt+enter选择转为Object[] array
        System.out.println(Arrays.toString(array));//[200, 300, 400, 500]
        // 只是类型发生变化,元素没有变化

        //4.测试集合间的操作
        Collection<Integer> c2 = new ArrayList<>();
        c2.add(2);
        c2.add(3);
        c2.add(4);
        System.out.println(c2);

        c.addAll(c2); //将c2集合的所有元素添加到c集合中
        System.out.println(c);//[200, 300, 400, 500, 2, 3, 4]
        System.out.println(c2);//c2集合不受影响

        System.out.println(c.containsAll(c2));//true 判断集合c2中的所有元素是否被c集合包含
        System.out.println(c.remove(2));//删除c集合中的元素2
        System.out.println(c);
        System.out.println(c.containsAll(c2));//false 集合c2中的2未被c集合包含

        System.out.println(c.removeAll(c2)); //删除c集合中属于c2集合的所有元素
        System.out.println(c);//[200, 300, 400, 500]

        c.add(4);
        System.out.println(c);//[200, 300, 400, 500, 4]
        System.out.println(c.retainAll(c2));//true 取c集合与c2集合的交集,保留其公共元素
        System.out.println(c);[4]//其都有元素4,所以保留公共元素4

               /* 迭代:
           1. 获取集合的迭代器 c2.iterator
           2.利用迭代器进行判断,当前集合中是否有下一个可迭代的元素 it.hasNext()
           3.利用迭代器获取当前迭代的元素 ii.next()*/
        Iterator<Integer> it = c2.iterator(); //获取迭代器
        while (it.hasNext()){ //循环,判断是否有元素可以迭代
            Integer num = it.next();//根据迭代器获取本轮迭代到的元素
            System.out.println(num);//打印获取到的本轮迭代到的集合中的元素
        }
    }
}

为了更好的理解集合,我们需要首先引入一个概念:泛型

2 泛型

  1. 泛型不是指一种具体的类型,而是说,这里有个类型需要设置,那么具体设置成什么类型,得看具体的使用
  2. 泛型通常与集合一起使用,用来限制集合中元素的类型
    泛型设置了什么类型,那么这个集合只能存这个范类型的数据
  3. 泛型是一颗“语法糖”:
    1)泛型可以把报错的时机提前,用在编译期检查集合的数据类型,只要不是规定的类型,就报错,通不过编译
    2)泛型只能在编译时生效,编译通过后,说明符合语法,泛型就会被抛弃,字节码文件中没有泛型
  4. 泛型的类型必须是引用类型,比如Student,Integer
  5. 泛型方法:如果在方法上使用泛型,必须俩处同时出现:
    1)一个是方法的参数列表中的参数类型
    2)一个是返回值前的泛型类型 ,表示这是一个泛型方法

2.1 概念

我们可以观察一下,下面的代码中有什么元素是我们之前没见过的呢?
在这里插入图片描述
其实就是< ? >的部分,它就是泛型
泛型是(Generics)JDK1.5 的一个新特性,通常用来和集合对象一起使用
泛型概念非常重要,它是程序的增强器,它是目前主流的开发方式

2.2 作用

那泛型有什么作用呢?
我们可以把泛型理解成一个“语法糖”,本质上就是编译器为了提供更好的可读性而提供的一种小手段,小技巧,虚拟机层面是不存在所谓“泛型”的概念的。是不有点神奇,不知所云,别着急等我讲完你就清楚了。

我们可以通过泛型的语法定义<>,来约束集合中元素的类型,编译器可以在编译期根据泛型约束提供一定的类型安全检查,这样可以避免程序运行时才暴露BUG,代码的通用性也会更强
泛型可以提升程序代码的可读性,但是它只是一个“语法糖”(编译后这样的部分会被删除,不出现在最终的源码中),所以不会影响JVM后续运行时的性能.

2.3 泛型示例

示例1 : 我们创建一个ArrayList,看到eclipse发出黄线警告,这是为什么呢?
原因:ArrayList定义时使用了泛型,在声明时需要指定具体的类型
在这里插入图片描述
在这里插入图片描述
我们把这个”<>”的方式称之为泛型,那么泛型有什么样的作用呢?就是在编译阶段检查传入的参数是否正确
在这里插入图片描述
有了泛型,我们可以看到要求存放的是String类型,而测试时存放的是int类型的100,所以编译器报错:
类型List的add方法要求添加的类型为String类型,int类型不匹配,不能正确存入

2.4 泛型声明

泛型可以在接口 类 方法上使用
在这里插入图片描述
在方法的返回值前声明了一个,表示后面出现的E是泛型,而不是普通的java变量

2.5 常用名称

在这里插入图片描述

2.6 练习:泛型测试

package cn.generic;

import java.lang.reflect.Array;
import java.util.ArrayList;

/* 本类用于泛型的入门
* 泛型的优点1*/
public class TestGeneric1 {
    public static void main(String[] args) {
        /* 泛型是怎么来的? 想要模拟数组的数据类型检查*/
        String[] s = new String[5]; //创建一个String类型的数组,长度为5
        s[0]="涛涛";
        s[1]="博博";
        //数组的好处:在编译的时候,就检查数据的类型,只要与数组的类型不匹配就报错,

        //如果集合不加泛型,集合中的元素类型没有约束,太广泛
        ArrayList list = new ArrayList();
        list.add("霞霞");
        list.add(666);
        list.add(3.14);
        list.add('a');
        System.out.println(list);

        /*在集合中引用泛型的概念,泛型通常和集合一起使用
          这样就可以利用泛型约束集合中的元素,除此之外:
          可以把报错的时机提前:只要元素的类型不匹配,在编译期就报错
          而不是运行代码时才报错,向集合中添加元素时,也会自动执行类型检查*/
        ArrayList<String> list2 = new ArrayList();
        list2.add("雷神");
        //list2.add(1);
        //list2.add(5.5);
        //list2.add('a');

        /* 4.<type> -- 这个type的值应该怎么写?
        *  需要根据集合中存入的元素类型做决定,但是type必须是引用类型,不能是基本变量类型
        * 所以,8大基本类型的泛型,应该使用其对应的包装类型,比如int---Integer*/
        ArrayList<Integer> list3 = new ArrayList();
    }
}

2.7 练习:泛型测试2

package cn.generic;
/*本类用于测试泛型的优点2*/
public class TestGeneric2 {
    public static void main(String[] args) {
        //需求:打印下列数组中的所有元素
        Integer[] a = {1,2,3,4,5,6,7,8,9,10};
        print(a);

        String[] b = {"大哥","二哥","三哥","四哥","五哥","六哥","小弟",};
        print(b);

        Double[] c = {6.6,6.66,6.666,6.6666};
        print(c);
    }

    /*1.泛型可以实现更加通用高级的代码,使用E表示元素的类型是Element类型
    *   可以把这个理解成与多态相似,不管传入什么类型,都可以匹配的上
    * 2. 泛型方法的语法要求:如果在方法上使用泛型,必须俩处同时出现:
    *    一个是方法的参数列表中的参数类型,一个是返回值前的泛型类型<E>
         表示这是一个泛型的方法*/
    private static <E> void print(E[] e){
        for (E n : e){
            System.out.println(n);
        }
    }

//    private static void print(Integer[] a){
//        //遍历数组a,打印a数组所有元素到控制台
//        for (int i=0; i<a.length; i++){
//            System.out.println(a[i]);
//        }
//        /* 高效for循环--foreach循环:
//        *  语法:for(1 2 : 3){循环体}
//        * 1:本轮遍历到的数据类型  2:遍历到数据的名字  3:要遍历的数据
//        * 好处:比普通的for循环写法简单,效率比较高
//        * 坏处:没有办法按照下标操作值,只能从头到位的遍历数据*/
//        for (Integer n : a){
//            System.out.println(n);
//        }
//    }
//
//    private static void print(String[] b){
//        for (String n : b){
//            System.out.println(n);
//        }
//    }
//
//    private static void print(Double[] c){
//        for (Double n : c){
//            System.out.println(n);
//        }
//}
}

3 List接口

3.1 概述

有序的colletion(也称为序列).此接口的用户可以对列表中的每个元素的插入位置进行精确的控制,用户可以根据元素的整数索引(在列表中的位置)来访问元素,并搜索列表中的元素.

3.2 特点

  1. 元素都有下标
  2. 数据是有序的
  3. 允许存放重复的元素

3.3 List方法速查表

在这里插入图片描述

3.4 练习:List接口测试

package cn.tedu.collection;

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

/**本类用于测试List接口*/
package cn.collection;

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

/* 本类用于List接口的练习*/
public class TestList {
    public static void main(String[] args) {
        //创建list接口的多态对象,因为是接口,所以不能直接创建,需要使用Arraylist
        List<String> list = new ArrayList<>();

        //2.练习继承自Collection父接口的方法
        list.add("大力娃");  //想list集合中存入数据
        list.add("千顺娃");
        list.add("头铁娃");
        list.add("喷火娃");
        list.add("喷水娃");
        list.add("隐身娃");
        list.add("紫娃娃");
        System.out.println(list); //打印查看集合中的数据

        //list.clear();  //清空集合
        //System.out.println(list);  //[]
        System.out.println(list.contains("喷火娃"));//true,判断集合是否包含指定元素
        System.out.println(list.equals("喷水娃"));//false,集合对象与String数据不等
        System.out.println(list.isEmpty());//false,判断集合是否为空
        System.out.println(list.remove("紫娃娃"));//移除集合中指定的元素
        System.out.println(list.size());//6,获取集合中元素的个数
        System.out.println(Arrays.toString(list.toArray()));//将集合转成数组

        //3.测试List接口自己的方法--List有序,可以根据索引来操作集合中的元素
        list.add("发福蝶");//追加在最后
        list.add(1,"大蟒鞋");//在指定的索引处添加元素
        list.add(3,"大脑斧");//在指定的索引处添加元素
        System.out.println(list);

        System.out.println(list.indexOf("发福蝶"));//3,获取指定元素第一次出现的索引
        System.out.println(list.lastIndexOf("发福蝶"));//8,获取指定元素最后一次出现的索引

        System.out.println(list);
        //根据索引删除元素,并将被删除的元素返回
        System.out.println(list.remove(2));  //根据索引删除集合中的元素
        System.out.println(list); //蛇精被删除
        System.out.println(list.get(3));//获取指定索引处的元素
        System.out.println(list.set(7,"蝎子精"));//修改指定索引处元素的值为蝎子精
        System.out.println(list);  //紫娃娃被换成蝎子精

        //集合间的操作
        List<String> list2 = new ArrayList<>();//创建第2个集合
        list2.add("1");//向集合2中添加元素
        list2.add("2");
        list2.add("3");
        list2.add("4");
        System.out.println(list2);//查看集合中的元素
        System.out.println(list.addAll(list2));//将2集合的所有元素追加到list集合的末尾
        System.out.println(list);  //打印添加元素后的list

        System.out.println(list.addAll(1,list2));//在list指定索引处,添加list2的所有元素
        System.out.println(list);  //打印添加元素后的list
    }
}

3.5 练习:List接口测试2

package cn.collection;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

/* 本类用于进一步测试List接口的练习*/
public class TestList2 {
    public static void main(String[] args) {
        //1.创建多态对象
        List<String> list = new ArrayList<>();
        //2.向接口中添加元素
        list.add("喜羊羊");
        list.add("美羊羊");
        list.add("懒羊羊");
        list.add("小肥羊");
        list.add("肥牛卷");
        System.out.println(list);

        //3.测试集合的迭代
        /* 集合的迭代方式:
        1.for循环
        2.foreach 高效for循环
        3.iterator
        */
        //方式一:因为List集合是有序的,元素有下标的,所以可以根据下标进行遍历
        //从哪开始:0  到哪结束:list.size()-1  如何变化++
        //i代表的就是集合中元素的索引值
        for(int i = 0;i<list.size();i++){
            //根据本轮循环遍历到的索引值获取对应的集合元素
            System.out.println(list.get(i));
        }
        System.out.println("************方式一结束*************");

        //方式二:因为普通for循环遍历效率低,语法复杂,所以使用高效for来遍历
        //格式for(本轮遍历到的元素类型 元素名 :要遍历的内容名){循环体}
        for( String s : list){
            System.out.println(s);
        }
        System.out.println("************方式二结束*************");

        //方式三:从父接口中继承过来的迭代器iterator
        //1.获取对应的迭代器对象
        Iterator<String> it = list.iterator();
        //2.通过刚刚获取到的迭代器循环迭代集合中的所有元素
        while(it.hasNext()){//判断是否仍有下一个元素可以迭代
            System.out.println(it.next());//打印当前获取到的元素
        }
        System.out.println("************方式三结束*************");

        /**方式四:listIterator属于List接口特有的迭代器
         * Iterator<E>--父接口--hasNext() next()
         * ListIterator<E>--子接口--除了父接口的功能以外
         * 还有自己的特有功能,比如逆序遍历,添加元素等等,但是不常用
         * public interface ListIterator<E>extends Iterator<E>*/
        //1.获取迭代器对象
        ListIterator<String> it2 = list.listIterator();
        //2.判断是否有下一个元素可以迭代
        while(it2.hasNext()){
            System.out.println(it2.next());
        }
        System.out.println("************方式四结束*************");

        System.out.println("listIterator的逆序遍历:");
        ListIterator<String> it3 = list.listIterator();
        while(it3.hasNext()){//判断是否有下一个元素可迭代
            System.out.println(it3.next());//打印当前迭代到的元素
            if(!it3.hasNext()){//直到迭代器没有下一个元素可迭代--到最后了
                System.out.println("开始逆序迭代:");
                while (it3.hasPrevious()){//判断是否有上一个元素可迭代
                    System.out.println(it3.previous());//打印获取到的上一个元素
                }
                break;//终止循环,不然会一直从头到尾,再从尾到头迭代
            }
            System.out.println("************方式五结束*************");
        }
    }
}

4 ArrayList

4.1 概述

  1. 存在java.util包中
  2. 内部是用数组结构存放数据,封装数组的操作,每个对象都有下标
  3. 内部数组默认的初始容量是10,如果不够会以1.5倍的容量增长
  4. 查询快,增删数据效率会低
    在这里插入图片描述
    在这里插入图片描述

4.2 创建对象

![在这里插入图片描述](https://img-blog.csdnimg.cn/82682a12efea4717b7787c7086df45af.png

4.3 练习:ArrayList测试

package cn.collection;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;

/**本类用于ArrayList相关测试*/
public class TestArrayList {
    public static void main(String[] args) {
        //1.创建对应的集合对象
        /**底层会自动帮我们创建数组来存放对象,并且数组的初始容量是10*/
        ArrayList<Integer> list = new ArrayList();

        //2.向集合中添加元素,用于测试
        list.add(100);
        list.add(200);
        list.add(300);
        list.add(400);
        list.add(400);
        list.add(300);
        System.out.println(list); //打印查看集合中的元素

        //3.测试常用方法
        //list.clear();  //清空集合

        System.out.println(list.contains("100"));//false  因为这个100是字符串
        System.out.println(list.get(0));//100,根据下标获取元素
        System.out.println(list.indexOf(400));//3,判断指定元素第一次出现的位置
        System.out.println(list.lastIndexOf(400));//4,判断指定元素最后一次出现的位置
        System.out.println(list.remove(0)); //删除集合中0号索引处的元素

        //System.out.println(list.remove(300));
        /**上面的代码会报错:数组下标越界:index:300 size:5
         * 数组中传入的是integer,是引用类型,不是基本类型,输入300默认为元素位置
         * 主要是因为List中有两个重载的remove(),如果传入的是300
         * 会认为是int类型的index索引,所以如果想指定元素删除数据
         * 需要把int类型的300手动装箱成Integer类型*/
        System.out.println(list.remove(Integer.valueOf(300)));

        System.out.println(list);
        System.out.println(list.size());//获取集合中元素的个数
        System.out.println(list.set(0,77));//修改指定位置的值

        //4. 迭代集合
        //4.1 使用for循环
        System.out.println("------------方式1-------------");
        for (int i=0; i<list.size(); i++){//循环集合
            System.out.println(list.get(i));//根据本轮循环到的索引获取集合中对应的元素
        }
        //4.2 使用高效循环
        System.out.println("------------方式2-------------");
        for(Integer num :list){//for(元素类型 元素名  : 要遍历的集合名){循环体}
            System.out.println(num); //打印每轮遍历到的元素
        }
        //4.3 使用 Iterator
        System.out.println("------------方式3-------------");
        Iterator<Integer> it = list.iterator();//获取迭代器对象
        //循环迭代集合中的所有元素
        while(it.hasNext()){//判断是否有下一个元素可迭代,如果有,继续循环
            System.out.println(it.next());//打印本轮迭代到的元素
        }
        //4.4 使用 ListIterator
        System.out.println("------------方式4-------------");
        ListIterator<Integer> it2 = list.listIterator(); //获取迭代器对象
        //循环迭代集合中的所有元素
        while(it2.hasNext()){//判断是否有下一个元素可迭代,如果有,继续循环
            System.out.println(it2.next());//打印本轮迭代到的元素
        }
    }
}

== 我们集合中存入的类型是引用类型,不是基本类型
如果想根据元素删除数据,需要把int类型参数转为集合中的元素类型integer==

ArryaList:
List接口的实现类,底层的数据结构为数组,内存空间是连续的

  1. 元素有下标,有序
  2. 允许存放重复的元素
  3. 在数据量较大的情况下,增删慢,查询快

5 LinkedList

5.1 概念

链表,两端效率高,底层就是链表实现的
在这里插入图片描述
在这里插入图片描述

LinkdList:
List接口的实现类,底层的数据结构为链表,内存空间是不连续的

  1. 元素有下标,有序
  2. 允许存放重复的元素
  3. 在数据量较大的情况下,查询慢,增删快

注意比较ArayList与LinkdList:ArrayList底层是数组结构,查询快,增删慢,适合查询较多的场景
LinkdList底层是链表结构,查询慢,增删快,适合增删操作比较多的场景
LinkedList查询慢是指数据量大时,要查询中的数据会比较慢,首尾查询操作还是比较快的

5.2 创建对象

LinkedList() 构造一个空列表

5.3 常用方法

void addFirst(E e) 添加首元素
void addLast(E e) 添加首元素
E getFirst() 获取首元素
E getLast() 获取尾元素
E element() 获取首元素
E removeFirst() 删除首元素
E removeLast() 删除尾元素

boolean offer(E e) 添加尾元素
boolean offerFirst(E e) 添加首元素
boolean offerLast(E e) 添加尾元素
E peek() 获取首元素
E peekFirst() 获取首元素
E peekLast() 获取尾元素
E poll() 返回并移除头元素
E pollFirst() 返回并移除头元素
E pollLast() 返回并移除尾元素

5.4 练习:LinkedList测试

package cn.collection;

import java.util.LinkedList;

/*本类用于测试LinkedList方法的使用*/
public class TestLinkedList {
    public static void main(String[] args) {
        //1.创建集合对象
        LinkedList<String> list = new LinkedList<>();
        //2.向集合中添加数据
        list.add("孙悟空");
        list.add("猪八戒");
        list.add("唐三藏");
        list.add("沙师弟");
        list.add("白龙马");
        System.out.println(list);

        //3.1 自行测试继承自Collection与list中的方法

        //3.2 测试LinkedList独有的方法
        list.addFirst("蜘蛛精");//添加首元素
        list.addLast("白骨精");//添加尾元素
        System.out.println(list);

        System.out.println(list.getFirst());//获取首元素  可以直接写到打印语句中,也可以单独写
        System.out.println(list.getLast());//获取尾元素  可以直接写到打印语句中,也可以单独写

        System.out.println(list.removeFirst());//移除首元素,成功移除会返回移除的数据
        System.out.println(list);//打印移除后剩余的元素
        System.out.println(list.removeLast());//移除尾元素,成功移除会返回移除的数据
        System.out.println(list);//打印移除后剩余的元素

        //4.其他测试
        //4.1创建对象
        LinkedList<String> list2 = new LinkedList();
        //4.2添加数据
        list2.add("水浒传");
        list2.add("三国演义");
        list2.add("西游记");
        list2.add("红楼梦");
        System.out.println(list2);

        System.out.println(list2.element());//水浒传 获取但不移除此列表的首元素(第一个元素)
        /**别名:查询系列*/
        System.out.println(list2.peek());//获取但不移除此列表的首元素(第一个元素)
        System.out.println(list2.peekFirst());//获取但不移除此列表的首元素(第一个元素)
        System.out.println(list2.peekLast());//获取但不移除此列表的尾元素(最后一个元素)

        /**别名:新增系列*/
        System.out.println(list2.offer("遮天"));//将指定元素添加到列表末尾
        System.out.println(list2.offerFirst("破天"));//将指定元素插入列表开头
        System.out.println(list2.offerLast("补天"));//将指定元素插入列表末尾
        System.out.println(list2);

        /**别名:移除系列*/
        System.out.println(list2.poll());//获取并且移除此列表的首元素(第一个元素),成功移除,返回移除元素
        System.out.println(list2.pollFirst());//获取并且移除此列表的首元素(第一个元素),成功移除,返回移除元素,如果此列表为空,则返回null
        System.out.println(list2.pollLast());//获取并且移除此列表的尾元素(最后一个元素),成功移除,返回移除元素,如果此列表为空,则返回null
        System.out.println(list2);
    }
}

6 扩展: ArrayList扩容

ArrayList相当于在没指定initialCapacity时就是会使用延迟分配对象数组空间,当第一次插入元素时才分配10(默认)个对象空间。假如有20个数据需要添加,那么会分别在第一次的时候,将ArrayList的容量变为10;之后扩容会按照1.5倍增长。也就是当添加第11个数据的时候,Arraylist继续扩容变为10*1.5=15;当添加第16个数据时,继续扩容变为15 * 1.5 =22个
ArrayList没有对外暴露其容量个数,查看源码我们可以知道,实际其值存放在elementData对象数组中,那我们只需拿到这个数组的长度,观察其值变化了几次就知道其扩容了多少次。怎么获取呢?只能用反射技术了。
在这里插入图片描述
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值