Collection之list源码分析

FLINKSQL自定义UDF函数1之collect_list&collect_set FLINKSQL自定义UDF函数1之collect_list&collect_set` 文章目录FLINKSQL自定义UDF函数1之collect_list&collect_set`前言一、collection_list1.编写CollectList类注意点1.1类型的输入1.2方法1.3测试结果展示2.collection_set注意点1.1这里我使用Set直接作为ACC有问题1.2 测试结果总结 前言 由于flink里面没有hive的collection_list以及collectio 阅读详情

Java中常用到ArrayList和LinkedList,面试中也常问到两者的区别,各自的使用场景。要想清楚的明白他们的区别,那还是得从源码入手。

List接口

List接口中的方法有很多,但最重要的无非是增删查改,我们从ArrayList与LinkedList的实现上来讨论他们的增删查改性能问题。先列出这几个重要的方法:

public interface List<E> extends Collection<E> {
    ...
    //增
    boolean add(E e); 
    void add(int index, E element);
    //查
    E get(int index);
    //改
    E set(int index, E element);
    //删
    E remove(int index);
    boolean remove(Object o);
    ...
}

 

集合的关系图如下

LinkedList与ArrayList

它们都实现了List接口。但是内部实现上有些区别,我们具体看下。

 

插入操作

默认顺序插入

按照默认顺序插入,两者耗费的时间都是O(1)。

  // LinkedList add操作
    public boolean add(E e) {
        linkLast(e);
        return true;
    }
    // 新建一个节点。然后让最后一个节点指向新加入的节点
    // 如果最后一个为空,那么这是第一个新插入的节点
    // 否则,节点按链表方式接在后面
     void linkLast(E e) {
        final Node<E> l = last;
        final Node<E> newNode = new Node<>(l, e, null);
        last = newNode;
        if (l == null)
            first = newNode;
        else
            l.next = newNode;
        
        // 增加大小,增加修改次数
        size++;
        modCount++;
    }
// ArrayList插入
    public boolean add(E e) {
        // 确保数组的容量足够。这个方法感兴趣可以看一下。
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }
    

 

指定index插入元素

ArrayList的最坏情况下性能为O(n),最好情况下为O(1)
LinkedList在任何情况下都是O(1)

// LinkedList
   public void add(int index, E element) {
        checkPositionIndex(index);

        if (index == size)
            linkLast(element);
        else
            linkBefore(element, node(index));
    }
    
    // LinkedList节点的查找方法
        Node<E> node(int index) {
        // 不断的遍历索引的位置。
        // 如果index 为小于size的一半,从头遍历
        // index 大于size的一半,从尾部索引
        if (index < (size >> 1)) {
            Node<E> x = first;
            for (int i = 0; i < index; i++)
                x = x.next;
            return x;
        } else {
            Node<E> x = last;
            for (int i = size - 1; i > index; i--)
                x = x.prev;
            return x;
        }
    }
    
    // 直接修改要插入
    void linkBefore(E e, Node<E> succ) {
        // assert succ != null;
        final Node<E> pred = succ.prev;
        final Node<E> newNode = new Node<>(pred, e, succ);
        succ.prev = newNode;
        if (pred == null)
            first = newNode;
        else
            pred.next = newNode;
        size++;
        modCount++;
    }
    
  //ArrayList 。
    //需要调用 System.arraycopy 扩充数组,数组中的元素都往后挪一个位置,在底层实现上应该是进行了(n-index)次的赋值操作。
    public void add(int index, E element) {
        rangeCheckForAdd(index);

        ensureCapacityInternal(size + 1);  // Increments modCount!!
        System.arraycopy(elementData, index, elementData, index + 1,
                         size - index);
        elementData[index] = element;
        size++;
    }

删除操作

删除元素,与插入本质上是类似的,有兴趣可以阅读JDK内部实现方式。
ArrayList的删除操作最差情况下性能为O(n),最好为O(1),删除最后一个元素的时候性能为O(1)
LinkedList删除任何元素的性能都为O(1)

搜索元素

ArrayList的搜索性能为O(1)
LinkedList的搜索性能差一些,最差为O(n/2)



 

//LinkedList的搜索
public E get(int index) {
        checkElementIndex(index);
        return node(index).item;
    }
    
    Node<E> node(int index) {
        // assert isElementIndex(index);
        // 需要进行链表的遍历
        if (index < (size >> 1)) {
            Node<E> x = first;
            for (int i = 0; i < index; i++)
                x = x.next;
            return x;
        } else {
            Node<E> x = last;
            for (int i = size - 1; i > index; i--)
                x = x.prev;
            return x;
        }
    }
// ArrayList搜索
    public E get(int index) {
        rangeCheck(index);

        return elementData(index);
    }
    
    //直接从数组的下标拿到元素即可。
    E elementData(int index) {
        return (E) elementData[index];
    }

 

想要获取线程安全的List

List list = Collections.synchronizedList(new ArrayList());
...
synchronized(list) {
      Iterator i = list.iterator(); // 必须在 synchronized 块中
      while (i.hasNext())
          foo(i.next());
  }

 

总结

  • ArrayList因为是基于动态数组去实现,在随机存取时,有着良好的性能。而增删时需要扩容,整块移动元素,所以相对较慢。但在数据量很大,顺序添加时是个例外,这种情况下它的性能优于LinkedList。
  • LinkedList因为是基于链表实现,随机增删较快,而存取时需要遍历查询,相对于ArrayList会更慢。
  • 之后会比较下两种实现的迭代器性能。
  • 它们都不是非线程安全的。
  • 因为ArrayList要维护索引结构(下标)所以在频繁的插入和删除的时候,性能比LinkedList慢,但是也正因为有着索引下标在做查询搜索的时候,性能比LinkedList快。
  • 使用场景:1.在频繁的插入和删除的时候,可以考虑使用LinkedList

                      2.在频繁的搜索的时候,考虑使用ArrayList

 

最后来比较下Vector、ArrayList和LinkedList

1)Vector和ArrayList

相同点:两者都是基于存储元素的数组来实现的,它们会在内存中开辟块连续的空间来存储,由于数据存储是连续的,它们支持用序号(下标)来访问元素,但是插入和删除是要移动容器中的元素,所以执行较慢。两者都有一个初始化的容量的大小,为10;当里面存储的元素超过这个大小时,就会动态的进行扩容。Vector默认扩充为原来的2倍,ArrayList默认扩充为原来的1.5倍。

区别:二者最大的区别在与synchronization(同步)的使用。在ArrayList中没有一个方法是同步的,而在Vector中,绝大部分方法都是同步的。所以Vector是线程安全的,而ArrayList不是线程安全的。由于Vector提供同步,所以性能上较低于ArrayList。

2)ArrayList和LinkedList

  • ArrayList是实现了基于动态数组的数据结构,而LinkedList是基于双向链表的数据结构
  • 对于随机访问,ArrayList要优于LinkedList,因为LinkedList要移动指针
  • 对于插入和删除,LinkedList较占优势,ArrayList要移动数据。
  • ArrayList和LinkedList都是非线程安全的容器

在实际使用中,若对数据的主要操作为索引或只在集合的末端增加、删除元素,使用Arraylist和vector效率比较高;若对数据的操作主要为指定位置的插入或删除操作,使用Linkedlist效率比较高;当在多线程中使用容器时(即多个线程会同时访问该容器,),选用vector较为安全。


参考:
链接:https://www.jianshu.com/p/de271d35591c

链接:https://www.jianshu.com/p/1df64730af96

使用Spark的`collect_list`函数按照其他列排序 函数按照其他列进行排序。你可以根据自己的需求修改代码,并尝试在实际项目中应用这些技术。首先,让我们假设我们有一个包含两列数据的DataFrame,其中一列是要排序的列,另一列是要聚合的列。函数时按照其他列的值进行排序。本文将介绍如何在Spark中实现这一功能,并提供相应的源代码。函数是一种聚合函数,它可以将一列的值收集到一个列表中。在Spark中,我们经常需要对数据进行排序和聚合操作。列的值收集到一个列表中,并将结果存储在名为。通过以上代码,我们成功地使用了Spark的。进行排序,并将结果存储在名为。 阅读详情

相关推荐

【Python】多分类算法—Random Forest

【Python】多分类算法—Random Forest 本文将主要就Random Forest(随机森林)的多分类应用进行描述,当然也可运用于二分类中 文章目录【Python】多分类算法—Random Forest前言一、pandas是什么?二、使用步骤1.引入库2.读入数据总结 前言 本文主要引用的是sklearn 一、pandas是什么? 示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。 二、使用步骤 1.引入库 代码如下(示例): import nump

weixin_43166884的博客 1万+

JAVA:Collection分支之List下三个子类的底层源码分析(1),ArrayList

一,创建一个ArrayList对象时,如果没有给它附上参数,那么ArrayList底层源码会将这个集合的大小默认为0,当我们给这个集合添加元素时,初次添加元素时,底层的源码会给集合大小从0扩大到10的容量,再次添加元素时,底层的源码会比较集合元素的长度和集合的大小,如果发现集合大小不够添加新的元素,则会按原来的集合大小的1.5倍扩容,也就是变到15. 无参ArrayList底层源码分析: 如上图,我们创建一个ArrayList对象并遍历填充,一开始的时候是调用无参构造器的,此时的集合大小为0。

m0_58229878的博客 333

人工智能机器学习从入门到高级学习资料(含资料下载地址)

机器学习是一个技术含量较高的领域,高效学习需要多种途径相结合.以下是一些推荐的学习资源。首先介绍几个比较有用的社区,包含了丰富的学习资料

2401_86900375的博客 1648

lambda表达式:Collectors源码解析

Collectors 源码解析 对于Collectors静态工厂类来说,其实现一共分为两种情况: 通过内置CollectorImpl来实现 通过reducing方法来实现,reducing方法本身又是通过CollectorImpl来实现的 mapping /* 将流中数据执行mapper映射,映射的数据存到传过来的收集器当中 Set<String> collect = list.stream() .collect(Collectors.mapping(x -> x +

qq_42261668的博客 943

告别ROS1!在Ubuntu 22.04上为VINS-Fusion适配ROS2 Humble的完整踩坑记录

本文详细记录了在Ubuntu 22.04上将VINS-Fusion从ROS1迁移到ROS2 Humble的完整过程,包括环境搭建、依赖管理、核心代码适配及性能优化。通过实战案例和调试技巧,帮助开发者高效解决迁移过程中的常见问题,提升系统稳定性和性能。

weixin_42628688的博客 281

多节阶梯阻抗变换器工程设计的公式推导

  多节阶梯阻抗变换器工程设计的公式推导,仔细看此文,有点烧脑,所以碎片十分钟,收获一丢丢。   现在就来设计一个超宽带多节阶梯阻抗变换器,要求带内纹波符合切比雪夫分布。   其实,此文已经是省去了大量中间公式推导,只剩下精炼内容了。   阶梯阻抗变换器指标需求   假设现在有一项目需求分析结果是:做一个微带线超宽带阶梯阻抗变换器,指标如下:   从50欧变换到100欧;   回波损耗22dB;   功率容量:2W;   频率范围2~18GHz;   插损能做多少就多少,用30mil板厚.

wusuowei1010的博客 7809

(一)jdk源码分析之collection,List,Set

前言 标题取得有点大,一口气分析三块的源码,看上去是个很大的话题,不过在个人看来,一方面,这三个都是接口,不涉及代码实现,读起来比较快,另一方面,大家都知道List,Set这两个接口都继承自collection,他们之间存在关联,所以放在一块分析讨论最能凸显,这三块接口的区别和特色。 Collection public interface Collection&lt;E&gt; exten...

secretmiyu的博客 185

NXP S32K3 Safety软件生态全解析:RTD、SPD、SAF、SCST到底怎么选?

本文深入解析NXP S32K3系列MCU的安全软件生态,详细对比RTD、SPD、SAF和SCST四大组件的功能定位与选型策略。针对不同ASIL等级需求,提供从架构设计到工程实践的完整解决方案,帮助开发者高效实现功能安全认证,优化汽车电子系统的安全性与可靠性。

weixin_42524226的博客 324

Java Collection(List+Set+Map)学习笔记 &附源码分析

集合框架的概述 集合和数组都是对多个数据进行存储操作的结构,简称Java容器 此时的存储,主要指的是内存层面的存储,不涉及到持久化的存储 数组与集合 数组在存储多个数据方面的特点 一旦初始化后,其长度确定 比如:String[]arr,int[] 一旦定义好,元素的类型也就确定了。 数组缺点...

qq_39063526的博客 348

【信号与系统】Multisim 仿真信号合成与分解

软件 Multisim 进行方波信号的产生、分解和合成,观察信号波形的分解与合成,加深对信号频谱的理解。

AXYZdong的博客 2万+

《模型轻量化-剪枝蒸馏量化系列》YOLOv5无损剪枝(附源码)

无损剪枝模型到几百kb~

cv君的博客 3万+

集合源码分析之02-Collection02--List

LIst为一个接口类,主要实现了Collection接口 出了重新写了一些包含Collection方法外,还添加了一些额外的方法 //添加所有在某个位置 boolean addAll(int index, Collection<? extends E> c); default void replaceAll(UnaryOperator<E> operator) { Objects.requireNonNull(operator); final

qqzhengwei的专栏 163

Yocto系列讲解[入门篇] 1 - 快速入门熟悉Yocto的构建

yocto quick start up带大家快速上手

fulinux的博客 5万+

Collection集合(非常重要的一章,涉及到List、Set、Map,HashMap的底层源码分析,面试基本必问)

java基础的很重要的一章,集合,Collection,包括三大部分,list,map,set。涉及到这些的源码分析以及底层的数据结构实现。比如面试常考的HashMap的底层结构就是数组+链表+红黑树,如何扩容。掌握了这一章,面对一些需要自己设计数据结构的算法题会轻松一些。

m0_46335449的博客 1124

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

JDK Collection 源码分析(2)—— List

JDK List源码分析 List接口定义了有序集合(序列)。在Collection的基础上,增加了可以通过下标索引访问,以及线性查找等功能。 整体类结构 1.AbstractList 该类作为List的通用骨架实现,和AbstractCollection一样,也是为了减少实现该接口的工作量。为了实现一个只读的List,仅仅只需要实现get和size方法即可。而对于读写的List,...

diaoxie6172的博客 143

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

JAVA-基础(Collection集合和List集合)

Collection集合概述是单例集合的顶层接口,它表示一组对象,这些对象也称为Collection的元素JDK 不提供此接口的任何直接实现.它提供更具体的子接口(如Set和List)实现创建Collection集合的对象多态的方式具体的实现类ArrayListCollection集合常用方法方法名说明添加元素从集合中移除指定的元素根据条件进行移除清空集合中的元素判断集合中是否存在指定的元素判断集合是否为空集合的长度,也就是集合中元素的个数。

weixin_57379543的博客 941

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Java集合源码分析(Collection、List、ArrayList、未完)

集合源码阅读 这里的图片罗列了接下来需要学习的内容,我的话首先从List入手 Collection接口 作为Java中所有集合的根接口,Collection中规定的基本内容并不多,我们首先看源码中官方的描述???? The root interface in the collection hierarchy. A collection represents a group of objects, known as its elements. Some collections allow duplic

weixin_45758209的博客 317

源码分析一(Iterator、Collection以及List接口)

1:Iterable接口,实现这个接口的类对象可以进行迭代 1 package java.lang; 2 import java.util.Iterator; 3 /** 4 * 实现这个接口的类所创建的对象可以进行迭代 5 */ 6 public interface Iterable&lt;T&gt; { 7 8 /** 9 * 调用这个方法会返回迭代...

weixin_33911824的博客 76

List源码分析

List源码分析 List List 是继承Colection的接口 我们主要学习他的实现类 ArrayList 和 LinkedList ArrayList ArrayList是基于数组实现的 与数组不同的是 它可以存放不同的数据类型的数据而且长度不定 // 我们分析一下他的底程实现 // 添加过程 public boolean add(E e) {// add方法就是我往里面添加元素 ...

Java_布丁 306

集合:Collection、List接口的常用方法及其扩容的源码分析

集合:Collection、List接口的常用方法及其扩容的源码分析

weixin_47384104的博客 218

Java集合进阶-Collection单列集合list集合set集合以及源码分析

Java集合进阶-Collection单列集合,list集合,set集合,ArrayList集合,LinkedList集合LinkedHashSet集合,TreeSet集合,以及源码分析使用场景,练习。

weixin_45170723的博客 255

容器1(Collection,set,list接口介绍、ArrayList底层源码分析、LinkedList源码分析、Vector和ArrayList的区别)

一、 Collection、set、list接口介绍 数组的优势:是一种简单的线性序列,可以快速地访问数组元素,效率高。如果从效率和类型检查的角度讲,数组是最好的。 数组的劣势:不灵活。容量需要事先定义好,不能随着需求的变化而扩容。 各接口的特点 Collection 接口存储一组不唯一,无序的对象 List 接口存储一组不唯一,有序(索引顺序)的对象 Set 接口存储一组唯一,无序的对象 map:每次存储 key-value对、 key部分不能重复、 常用实现类HashMap或TreeMap 1.Co

姓程名序种族猿 200

一文读懂,java list集合详解及arraylist,linkedlist集合底层源码分析

Collection集合概述是单例集合的顶层接口,它表示一组对象,这些对象也称为Collection的元素JDK 不提供此接口的任何直接实现.它提供更具体的子接口(如Set和List)实现创建Collection集合的对象多态的方式具体的实现类ArrayListCollection集合常用方法方法名说明添加元素从集合中移除指定的元素根据条件进行移除清空集合中的元素判断集合中是否存在指定的元素判断集合是否为空集合的长度,也就是集合中元素的个数List集合的概述。

m0_58975186的博客 1004

2接口详解_java集合【2】——— Collection接口详解

一、Collection接口简介二、Collection源码分析三、Collection的子类以及子类的实现3.1 List extend Collection3.2 Set extend Collection3.3 Queue extend Collection四、Collection和Map的辨析五、Collection和Collections的辨析六、总结 一、Collection...

weixin_29178069的博客 217
上一篇: 面试相关总结
下一篇: 入门级 开源SpringBoot+Vue项目
chao430
博客等级 码龄10年 38粉丝 63原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值