当前位置:首页 > 服务端 > 集合类Collection——List篇

集合类Collection——List篇

2022年11月09日 09:52:02服务端8

1.集合的出现:

由于数组的长度不可变,这时我们需要一个特殊的类,这些类可以存储任意类型的对象,并且长度可变,这些类统称为集合

集合按照存储结构可以分为两大类:分别是单列集合Collection和双列集合Map,在本篇文章中主要讲的是Collection集合。

Collection集合特点如下:

  • Collection是所有单列集合类的根接口,它用于存储符合某种规则的元素。
  • 它有两个子接口:Set和List

Set 和 List的区别:

  • Set的特点是元素无序且不可重复
  • List的特点是元素有序且元素可重复

集合类Collection——List篇 _ JavaClub全栈架构师技术笔记
其中Collection、List、Set都是接口类型,而它们其余的子类为具体的实现类。

Collection接口通用的一些方法示例:

public static void main(String[] args) {
     
        //创建一个集合类对象,并且使用具体的实现类
        Collection<Integer> coll = new ArrayList<>();
        coll.add(3);//向集合中添加元素3
        coll.clear();//清空集合,但集合本身还存在,[]
//        coll.removeAll(coll);//删除集合所有元素,功能同上
        System.out.println(coll.isEmpty());//判断集合是否为空,是返回true,不是返回false
        coll.add(4);
        System.out.println(coll);//打印集合所有元素
        System.out.println(coll.contains(4));//判断是否包含4这个元素
        coll.add(5);
        coll.add(6);
        coll.add(7);
        coll.remove(7);//删除元素7
        Iterator it = coll.iterator();//使用迭代器遍历该集合所有元素
        while (it.hasNext()){
     
            System.out.println(it.next());//打印每一个元素
        }
        System.out.println(coll.size());//获取该集合元素个数
    }

List接口:

  • List接口继承自Collection接口,是单列集合的一个重要分支,将实现了List接口的对象称为List集合。
  • List集合中允许出现重复的元素,所有的元素以一种线性的方式进行存储,在程序中可以通过索引来访问集合中的指定元素。
  • List集合还有一个特点就是元素有序,即元素的存入顺序和元素的取出顺序一致。

List的通用方法示例:

public static void main(String[] args) {
     
        List<String> list = new ArrayList<>();
        list.add("AMD");
        list.add("青菜");
        list.add("胡萝卜");
        list.add(0,"小米椒");
        list.add("AMD");
        System.out.println(list.get(1));
        list.set(2,"金针菇");
        list.remove(0);
        System.out.println(list);
        System.out.println(list.indexOf("AMD"));
        System.out.println(list.lastIndexOf("AMD"));
        //List的实现类都可以通过以下方式遍历集合
        System.out.println("======遍历集合的三种方式======");
        //for循环
        for (int i = 0; i < linked.size(); i++) {
     
            System.out.println(linked.get(i));
        }
        //迭代器
        System.out.println("------------");
        Iterator<String> it = linked.iterator();
        while (it.hasNext()) {
     
            System.out.println(it.next());
        }
        //foreach
        System.out.println("------------");
        for (String s : linked){
     
            System.out.println(s);
        }
    }

ArrayList:

  • ArrayList和数组一样,都有索引,它的索引从0开始,size-1结束。
  • ArrayList底层是使用一个数组来保存元素,在其内部封装了一个长度可变数组对象,当存入的元素超过数组长度时,ArrayList会在内存中分配一个更大的数组来存储这些元素。所以在增加或删除指定的位置的元素的时候,会导致创建新的数组,效率会很低下,因此不适合做大量的增删操作
  • 因为其含有索引的特殊性,如果是使用查找功能居多,可以采用ArrayList集合

ArrayList的通用方法示例:

public static void main(String[] args) {
     
        //创建一个ArrayList集合
        ArrayList<String> list = new ArrayList<>();
        list.add("AMD");//添加元素
        list.add("Per01");
        list.add("Per02");
        list.add("Per03");
        list.add("AMD");//AMD,YES!!!
        list.remove(2);//删除索引为2的元素Per02
        list.set(1,"YES");//将索引为1的元素值替换为YES
        System.out.println(list.get(1));//获取索引值为1的元素
        System.out.println(list.size());//获取集合的容量大小
        System.out.println(list.indexOf("AMD"));//返回“AMD”在集合中第一次出现的索引位置
        System.out.println(list.lastIndexOf("AMD"));//返回“AMD”在集合中最后一次出现的索引位置
    }

在上面讲到,如果向ArrayList集合存入的元素超过数组长度时,ArrayList会在内存中分配一个更大的数组来存储这些元素。
那么如何分配数组,分配多大数组呢?这就不得不提及到ArrayList的扩容机制

ArrayList的扩容机制:
在查询相关资料和对源码的分析得知:

  1. 创建ArrayList对象的时候:如果没有指定集合的容量,集合的默认容量为0
  2. 初始化:当第一次往里添加元素时,ArrayList将通过构造方法初始化一个容量为10的数组
  3. 扩容的时机:当往集合中添加第11个元素(超过当前数组的初始容量10)时,会进行扩容,扩容的容量为原始的1.5倍,即数组容量扩容变成(15、22、33、49…)
  4. 如果新增后的容量超过当前扩容的容量,即1.5倍的容量大小不够(例如使用addAll()方法,添加进来整个集合)。则集合容量为新增后所需的最小容量(即元素有多少个,容量就为多少)。
  5. 如果增加0.5倍后的新容量超过限制的容量,则用所需的最小容量(元素的个数)与限制的容量进行比对判断,如果超过则指定为Integer的最大值,否则指定为限制容量大小(如何理解: 当元素的个数超过了当前容量,需要进行扩容,变成原来的1.5倍大小时,如果超过了限制的容量(即规定的最大容量),会进行一个判断,判断你的元素是否能把1.5倍的集合填满,如果填满了,会使用Integer的最大值来作为容量的大小。否则,没有填满,就会采用MAX_ARRAY_SIZE,即所需的最小容量(元素的个数))
  6. 扩容的方式:当数组进行扩容的时候,会以新的容量(即1.5倍)建一个原数组的拷贝,修改原数组,使用Arrays.copyOf方法将elementData数组指向这个进行扩容后的新数组,原数组被抛弃,被GC进行垃圾回收。

上面我们提到,ArrayList的查询元素速度很快,但是在增删元素的时候效率会比较低,为了克服这种局限性,我们不得不提到它的另外的一个好兄弟LinkedList

LinkedList:

  • 由于Linked是List的实现类,所以它也有索引,从0开始,size-1结束
  • LinkedList集合的底层是维护了一个双向循环链表,链表中的每一个元素都使用引用的方式来记住它的前一个元素和后一个元素,从而可以将所有的元素彼此连接起来
  • 插入一个新元素或删除某一个结点时,只需要修改元素之间的这种引用关系即可。正是因为这样的存储结构,所以LinkedList集合对于元素的增删操作有着很的效率

LinkedList集合新增元素和删除元素的过程
集合类Collection——List篇 _ JavaClub全栈架构师技术笔记
新增一个元素时:元素1和元素2在集合中彼此为前后关系,在它们之间新增一个元素时,只需要让元素1记住它后面的元素是新元素,让元素2记住它前面的元素是新元素即可。

集合类Collection——List篇 _ JavaClub全栈架构师技术笔记
删除一个元素时:想要删除元素1和元素2之间的元素3,只需要让元素1和元素2相互引用,变成前后关系就可以了。

LinkedList通用方法示例:

public static void main(String[] args) {
     
        //创建LinkedList集合
        LinkedList<String> linked = new LinkedList<>();
        linked.add("stu1");//添加元素
        linked.add("stu2");
        linked.add("stu3");
        System.out.println(linked);//默认调用toString方法,打印集合所有元素
        linked.add(1,"Student");//指定索引位置插入元素
        linked.addFirst("First");//集合第一个位置插入元素
        linked.addLast("Last");
        System.out.println(linked.get(2));//获取索引为2的元素
        System.out.println(linked.getFirst());//获取第一个元素
        System.out.println(linked.getLast());
        linked.remove(3);//移除索引为3的元素
        linked.removeFirst();//移除第一个元素
        linked.removeLast();
    }

扩展: ListIterator接口:

我们知道,通过Iterator迭代器提供的hasNext()方法和next()这个两个方法可以实现集合中元素的迭代,且迭代的方向是从集合中的第一个元素向最后一个元素迭代,也就是所谓的正向迭代。为了使迭代的方式更加多元化,JDK还定义了一个ListIterator迭代器,它是Iterator接口的子类,通过此接口可以实现反向迭代集合元素。

不过要注意的是:ListIterator迭代器只能用于List集合
代码演示:

public static void main(String[] args) {
     
        ArrayList<String> list = new ArrayList<>();
        list.add("data_1");
        list.add("data_2");
        list.add("data_3");
        list.add("data_4");
        System.out.println(list);
        System.out.println("=============");
        ListIterator<String> it = list.listIterator(list.size());
        while (it.hasPrevious()) {
     
            System.out.println(it.previous());
        }
    }

Enumeration接口:

现在,我们遍历集合的时候可以使用 Iterator 接口,但在JDK1.2以前还没有 Iterator 接口的时候,遍历集合需要 Enumeration 接口,它的用法和 Iterator 类似,在很多的程序中依然使用Enumeration,所以了解是很有必要的。

Vector集合:

  • Vector集合是List的一个实现类,它的用法与 ArrayList 完全相同
  • 它和 ArrayList 区别在于:Vector集合是线程安全的,ArrayList 集合是线程不安全的
  • 在 Vector 类中提供了一个elements()方法用于返回Enumeration对象,通过Enumeration对象就可以遍历集合中的元素

代码演示:

public static void main(String[] args) {
     
        Vector<String> v = new Vector<>();
        v.add("stu1");
        v.add("stu2");
        v.add("stu3");
        Enumeration en = v.elements();
        while (en.hasMoreElements()) {
     
            System.out.println(en.nextElement());
        }
    }

作者:Java2h
来源链接:https://blog.csdn.net/weixin_43380871/article/details/105192214

版权声明:
1、JavaClub(https://www.javaclub.cn)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。

2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。


本文链接:https://www.javaclub.cn/server/68734.html

标签: List
分享给朋友:

“集合类Collection——List篇” 的相关文章

flutter中list相关操作汇总(有这一篇就够啦)

要说,List在我的开发使用中,确实是最为频繁的了,那么如何使用list,也就成了一个问题,list提供的方法又有哪些 这些都是需要掌握理解的。 首先第一个, 对于固定长度的list,如何删除添加元素呢 void main() {...

Java List转String数组与String数组转List

Java List转String数组与String数组转List

1. String数组转List String title = "\t 10月上旬\t 10月中旬\t 10月下旬"; String[] arrTitles = title.split("\t"); List<String> titl...

HTML5中datalist标签的使用

HTML5中datalist标签的使用

datalist是html5中出现的新标签,它需要配合input输入框来使用,它的作用就是定义了input可能要输入的值(可以被快捷选择), 定义一个datalist的标签需要给他一个id,input就是根据id来与其绑定的,datalist中的opti...

java 集合hashmap hashset arraylist 详解以及常见面试题

java 集合hashmap hashset arraylist 详解以及常见面试题

   今天复习了一下自认为java 中很重要的一部分集合,这篇文章主要从底层源码进行分析这几种集合的区别与联系,他们的用法不多讲,用法不难;大多数东西我也是从各位大神的博客上或者书上扒下来的,小菜鸟在复习,写下来主要是一:是为了想留下点东西 二:我发现在写的过程中我...

Java中ArrayList相关的5道面试题

本文参考了 《关于ArrayList的5道面试题 》  1、ArrayList的大小是如何自动增加的? 这个问题我想曾经debug过并且查看过arraylist源码的人都有印象,它的过程是:当试图在一个arraylist中增加一个对象时,Jav...

Java中List,String,String[]之间进行转换

String转换List package string; import com.google.common.base.Splitter; import com.google.common.collect.Lists; import org.apache.commons.l...

java jdk8 使用stream实现两个list集合合并成一个list集合(对象属性的合并)

java jdk8 使用stream实现两个list集合合并成一个list集合(对象属性的合并)

java使用stream实现list中对象属性的合并: 根据两个List中的某个相同字段合并成一条List,包含两个List中的字段 目录 一、前言 二、示例 示例1:java...

java中char类型的Arraylist如何转化成一个string

package secondpackage; import java.util.ArrayList; import java.util.List; public class ceshi2 { public static void main...

Java——string[] 和List的区别

一直对string[]和List<string>定义不怎么清楚,特地总结一下:        string[]数组里面是存放string型的值,List<string>是存放str...

Java获取集合List前几个数据

Java获取集合List前几个数据

List.subList(start,end); start:第一个元素下标; end:第n个元素 作者:圣殿骑士OS 来源链接:https://blog.csdn.net/weixin_43652811/article/det...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。