首页 > 其他分享 >List体系

List体系

时间:2024-09-27 18:48:50浏览次数:11  
标签:体系 ArrayList 元素 List al add println public

        查阅API,看List的介绍。有序的 collection(也称为序列)。此接口的用户可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。与 set 不同,该列表通常允许重复的元素。
        看完API,我们总结一下:
        List接口:

        它是一个元素存取一致的集合。例如,存元素的顺序是11、22、33。那么集合中,元素的存储就是按照11、22、33的顺序完成的)。
        它是一个带有索引的集合,通过索引就可以精确的操作集合中的元素(与数组的索引是一个道理)。
        集合中可以有重复的元素,通过元素的equals方法,来比较是否为重复的元素。

        那么下面我们重点来学习List接口两个重点儿子 ArrayList和LinkedList类。

1.ArrayList

         先来看一下ArrayList中特有方法。

ArrayList<E>中的方法(这里的E可以当作为Object类来理解,我这里举例使用String类型):
        public boolean add(E e):添加元素到列表末尾
        public void add(int index, E element):将指定元素添加到指定索引位置,该位置原有的元素及之后元素会后移
        public E get(int index):将指定索引位置的元素取出
        public E set(int index, E element):将指定位置的元素设置成新的值,并且返回该索引原有的值
        public E remove(int index):将指定索引位置的元素删除,并且返回要删除的元素

public class ArrayListDemo01 {
    public static void main(String[] args) {
        ArrayList<String> al = new ArrayList<>();
        al.add("张三");
        al.add("李四");
        //1.将指定元素添加到指定索引位置
        al.add(1,"王五");
        System.out.println(al);
        //2.将指定索引位置的元素取出
        System.out.println(al.get(2));
        //3.将指定位置的元素设置成新的值,并且返回该索引原有的值
        System.out.println(al.set(1,"赵六"));
        //4.将指定索引位置的元素删除,并且返回要删除的元素
        al.remove(0);
        System.out.println("经过上述一系列操作后集合中元素:"+al);
    }
}

1.1  ArrayList原理

ArrayList底层原理
        1.ArrayList从名字上推断(Array)底层使用的是数组结构
        2.new ArrayList()的时候,底层会创建一个空数组,即Object[] elementData =new Object[0];
        3.当首次调用add方法的时候,底层会开辟一个默认容量为10的Object数组
此时,Object[] elementData = new Object[10],用来存储第一个元素。

        对ArrayList<String> al = new ArrayList<>();进行Debug强制进入,如下图:

        而不难发现,这里的elementDate是一个Object类型的数组,且初始化为{ }。该数组的默认容量为10,即:

        再增加元素之后,直接打印集合会调用重写后的toString方法,如下图,可以看到,创建了一个迭代器,如果! it.hasNext()为true,即没有下一个元素,直接打印[ ]。否则往下执行,会创建一个StringBuilder容器,先把“【”加上,再遍历判断当前元素e是集合本身还是下一个普通元素,如果是普通元素就直接调用append追加再后面,最后跟上“】”,完成元素的添加。

        ArrayList的扩容原理类似于StringBuilder,这里不再展示具体操作,可以去参考StringBuilder的扩容解释,下面用图来理解ArrayList如何扩容:

1.2  ArrayList特点

        1.集合中元素有索引,有顺序,可以存储重复元素

        2.ArrayList集合增删慢,查询快  
  a.查询快:因为ArrayList底层是一个数组,而数组有索引,我们根据索引可以直接取出元素
          集合索引      0           1           2        3     4  ...   9
     ArrayList元素: "abc"    "def"     "ghk"   null  null ... null
     获取"ghk":根据索引直接可以取出元素 get(2)

   b.增删慢:如果我们要增删一个元素,会导致这个元素后面的所有元素往前或者往后挪动,可能会移动大量元素,导致ArrayList增删效率低
          集合索引                             0          1          2         3     4  ...  9
     ArrayList元素:                       "abc"   "def"   "ghk"  null null .... null
     添加一个"ml"到0索引位置      "ml"    "abc"   "def"  "ghk" null ... null
     当我们添加一个元素的时候,该元素之后的元素都要依次往后移动一个位置

          集合索引            0            1        2           3     4  ...  9
    ArrayList元素:         "abc"   "def"   "ghk"      null null .... null
    删除"abc"               "def"  "ghk"    null          null null .... null
            当我们删除一个元素的时候,该元素之后的元素都要依次往前移动一个位置

也可以看图片理解:

 1.3  ArrayList的三种遍历方式

        对于ArrayList集合的遍历,有常用的三种方法。分别是:迭代器遍历、(特有遍历方式)索引遍历、增强for遍历。
        首先看第一种,迭代器遍历:

public class ArrayListDemo03 {
    public static void main(String[] args) {
        ArrayList<String> al = new ArrayList<>();
        al.add("abc");
        al.add("def");
        al.add("qwe");
        Iterator<String> iterator = al.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }
}

        查看API发现ArrayList中有迭代器方法,那就可以使用迭代器来遍历集合中的元素,使用集合对象al来创建迭代器,再使用迭代器的hasNext( )判断是否有下一个元素,使用next()打印下一个元素,针对于迭代器的这两个方法:

        其实刚开始的时候hasNext()的指针指向的是第一个元素上方,此时判断存在下一个元素的时候,指针移动指向第一个元素。如图:

        当hashNext( )指向最后一个元素的时候,再进行判断就会返回false值,此时循环就停止了。也就循环遍历结束。

        最后运行结果图:

        再看第二种方式:索引遍历,也是ArrayList特有的遍历(其他集合没有索引)。

public class ArrayListDemo03 {
    public static void main(String[] args) {
        ArrayList<String> al = new ArrayList<>();
        al.add("abc");
        al.add("def");
        al.add("jdk");
        for (int i = 0; i < al.size(); i++) {
            System.out.println(al.get(i));
        }
    }
}

        这里的size方法和get方法上面提到过,size获取集合中有效元素数,get方法可以传入索引来返回指定的元素。

运行结果:

        最后看第三种:增强for遍历

public class ArrayListDemo03 {
    public static void main(String[] args) {
        ArrayList<String> al = new ArrayList<>();
        al.add("张三");
        al.add("李四");
        al.add("王五");
        for (String element:al){
            System.out.println(element);
        }
    }
}

        增强for语法:for(所遍历的数据类型  变量名:所遍历集合),所以直接输出结果为:

        其实对于ArrayList存储自定义引用类型,存储的仍是地址值,而并非对象本身。(这里省略了部分代码)直接可以看下图理解:
 

2.LinkedList

2.1  LinkedList原理

        LinkedList是基于一种双向链表的实现。LinkedList 类还为在列表的开头及结尾 get、remove 和 insert 元素提供了统一的命名方法,所有操作的执行都与双向链表的预期相同。可以看下图来理解LinkedList的实现原理。

再来说说LinkedList<E>中特有的方法:
        public void addFirst(E e):向集合的开头位置添加元素
        public void addLast(E e):向集合的末尾添加元素
        public E getFirst():获取集合头部的元素
        public E getLast():获取集合尾部的元素
        public E get(int index):取出指定位置的元素
        public E removeFirst():移除头部元素,并且返回当前被删除的元素
        public E removeLast():移除尾部的元素,并且返回当前被删除的元素

public class LinkedListDemo01 {
    public static void main(String[] args) {
        LinkedList<String> ll = new LinkedList<>();
        ll.add("abc");
        ll.add("def");
        //1.每一次都添加到最前面
        ll.addFirst("ghk");
        System.out.println(ll);//[ghk, def, abc]
        //2.向集合的末尾添加元素
        ll.addLast("poo");
        System.out.println(ll);//[ghk, abc, def, poo]
        //3.获取集合头部的元素
        System.out.println(ll.getFirst());//ghk
        System.out.println(ll);//[ghk, abc, def, poo]
        //4.获取集合尾部的元素
        System.out.println(ll.getLast());//poo
        System.out.println(ll);//[ghk, abc, def, poo]
        //5.取出指定位置索引元素
        System.out.println(ll.get(1));//abc
        System.out.println(ll);//[ghk, abc, def, poo]
        //6.移除头部元素,并且返回当前被删除的元素
        System.out.println(ll.removeFirst());//ghk
        System.out.println(ll);//[abc, def, poo]
        //7.移除尾部的元素,并且返回当前被删除的元素
        System.out.println(ll.removeLast());//poo
        System.out.println(ll);//[abc, def]
    }
}

    

2.2  LinkedList特点

        这里主要分析LinkedList基于双向链表的方式实现元素的增加删除查询。

       LinkedList增加或删除元素,效率相对于ArrayList较高, ArrayList每次添加 或删除 动作,可能需要移动大量的元素而LinkedList只需要改变元素记录的地址值就可以了
         尽管双向链表查询既能从头开始找,也能从尾开始找,但是LinkedList 查询效率相对于ArrayList 较慢,因为ArrayList可以根据索引直接取出元素,而LinkedList需要 顺链 或 逆链 杳找,

        具体看图理解:

3.集合的另一种初始化方式

        对于集合的初始化方式,我们一般写 ArrayList<String> al = new ArrayList<>();后再使用add方法增添元素,al.add("abc");,而另一种初始化方式我们也应能看懂和使用,如下:

public class ArrayListDemo02 {
    public static void main(String[] args) {
        //1.一般初始化方式
        ArrayList<String> al = new ArrayList<>();
        al.add("abc");
        al.add("def");
        System.out.println(al);
        
        //2.双大括号形式初始化集合
        ArrayList<String> al02 = new ArrayList<>(){
            {
                add("abc");
                add("def");
            }
            //相当于打印对象,但是最终还是会调用toString方法
        };
        System.out.println(al02);
        System.out.println(al02.getClass());
    }
}

        运行结果:

        代码中的1.中的初始化方式就是我们常用的,2.中的大括号形式就是另一种,对于理解,我们可以把大括号形式的初始化看成是:

class ArrayListDemo02$1 extends ArrayList<String>{
    {
        //构造代码块
        add("abc");
        add("def");
    }
    //继承了ArrayList的toString方法
}
ArrayList<String> al = new ArrayListDemo02$1(); 

        这种初始化方式相当于底层创建了一个名为 ArrayListDemo02$1 继承了Arraylist,然后通过父类ArrayList实现子类   ArrayListDemo02$1的对象al,我们可以通过getClass( )方法来验证一下:

        打印输出的class arraylist01.ArrayListDemo02$1也验证了我们的说法,对象al02引用指向对象使用的类是ArrayListDemo02$1,而不是直接输出的ArrayList,于我们前面所学到的匿名内部类的思想一样。针对于运行的原理,其实当我们new对象的时候,会先走构造代码块,构造代码块中有添加元素的方法,相当于把元素添加到集合中。

       

标签:体系,ArrayList,元素,List,al,add,println,public
From: https://blog.csdn.net/2301_77206753/article/details/142577996

相关文章

  • AI产品经理从入门到精通(知识体系非常详细)看这一篇就够了!!!
    AI产品经理知识体系:驾驭未来的核心技能随着人工智能(AI)的快速发展,AI产品经理的角色变得至关重要。他们不仅需要具备传统产品经理的技能,还必须深入理解AI技术的各个方面,才能推动AI技术在实际产品中的落地和应用。从最基础的技术知识,到跨领域的创新思维,AI产品经理的知识体系需......
  • 如何同时使用多个Craigslist账户而不被封禁?
    Craigslist作为美国最受欢迎的在线分类广告网站之一,无论是商务广告、招聘还是资讯都可以在上面进行。每月吸引约250万次访问,是扩大在线影响力的绝佳选择。尽管Craigslist允许创建多个账户,但在发布广告时存在一些限制。例如,你不能在48小时内在同一类别和城市发布相同的广告两次......
  • 如何同时使用多个Craigslist账户而不被封禁?
    Craigslist作为美国最受欢迎的在线分类广告网站之一,无论是商务广告、招聘还是资讯都可以在上面进行。每月吸引约250万次访问,是扩大在线影响力的绝佳选择。尽管Craigslist允许创建多个账户,但在发布广告时存在一些限制。例如,你不能在48小时内在同一类别和城市发布相同的广告两次......
  • 智慧防灾,科技先行:EasyCVR视频汇聚平台如何推动地质灾害防控体系的智能化升级
    随着科技的飞速发展,视频监控技术已成为地质灾害监测与预警的重要手段之一。在众多视频监控平台中,EasyCVR视频汇聚平台凭借其强大的视频整合、实时传输、视频处理及分发等能力,在地质灾害场景中展现出显著的应用优势。一、实时监测与远程监控EasyCVR视频汇聚平台能够实时接入并传......
  • listview中的edittext输入状态时不要刷新listview
    我的listview是时时刷新的,这导致了listview中的edittext不能点击编辑,通过如下方法解决了此问题,监测屏幕的变化,如果弹出软键盘,则不更新,问题解决。监测屏幕的代码如下ViewTreeObserverobserver=rootView.getViewTreeObserver();observer.addOnGlobalLayoutListener(newViewTreeO......
  • C# Linq.FirstOrDefault、Linq.Where、Linq.AsParallel、List.Exists、List.Find、Dic
    C#Linq.FirstOrDefault、Linq.Where、Linq.AsParallel、List.Exists、List.Find、Dictionar.TryGetValue、HashSet.Contains性能的比较 今天我们来比较一下集合检索方法性能更优问题,测试代码publicclassEntity{publicintId{get;set;}publicintNo{......
  • 关于Java中的List<User>如何进行深拷贝
    联调中发现了一个很初级,但有容易被忽略的拷贝问题:错误方式:List<User>us=newArrayList<>();List<User>us1=newArrayList<>(us);此种拷贝,如果修改了集合us中的User对象,us1会跟着改变;找了网上很多方式:1.clone方式us的方法里边不存在clone;2.addAll方法不是深度......
  • 数据资产管理实施路径盘点,一文读懂如何建设企业数据资产管理体系
    完备的企业数据资产管理体系,首先依赖于数据资产管理规划及机制等上层设计,其次基于数据资产管理职能,使用有效的数据资产管理工具,将数据转化为数据资产,从而把数据价值真正发挥出来。数据资产管理架构如下图所示:袋鼠云数据资产管理架构图具体而言,数据资产管理包括数据开发、数据标准管......
  • 【VUE】[Violation] Added non-passive event listener to a scroll-blocking...
    1.问题[Violation]Addednon-passiveeventlistenertoascroll-blocking<某些>事件.Considermarkingeventhandleras'passive'tomakethepagemoreresponsive.See<URL>译:[违规]向滚动阻止添加了非被动事件侦听器<某些>事件.请考虑将事件处理程序标记为“被......
  • 某房地产集团搭建员工培训体系项目纪实
    某房地产集团搭建员工培训体系项目纪实——完善员工培训体系,提高培训效果【客户行业】房地产行业【问题类型】培训体系【客户背景】某房地产公司隶属于某大型央企,主营业务涵盖房产开发、物业管理等房地产全产业链。依托央企的品牌和实力,充分发挥产业链协同、城市综合开发......