`

Java List转数组几种方式性能问题

阅读更多

List集合使用toArray方法转成数组,该方法重载了两种形式,无参的和有参的,有参的又可以指定目的数组的不同长度,根据数组长度和原有List元素个数(size)的比较又可以分为几种情况,每一种方式对性能的影响不一。本文主要以实例结合源码来分析不同情况性能问题,供实际工作和面试时参考。不多说,直接上干货

创建一个简单的List,插入3个元素

List<String> list1 = new ArrayList<>();
        list1.add("a");
        list1.add("b");
        list1.add("c");

方式1:使用无参toArray方法

Object[] arr1 = list1.toArray();
System.out.println("遍历arr1");
for (Object object : arr1) {
            //可能会有类型转换错误
            Integer i1 = (Integer)object;
            System.out.println(i1);
            
            System.out.println(object);
    }

该方式只能转成Object类型数组,原有集合指定的泛型消失,相当于类型擦除
隐患:如果拆箱时强转成其他类型,可能会出现ClassCastException,比如代码中的
Integer i1=(Integer)object 而且这种问题编译时不能识别,把问题隐藏到运行时

方式2:使用有参toArray方法

 public <T> T[] toArray(T[] a) {

** 该重载形式可以返回同List对应的泛型数组,保留了元素类型信息,避免了方式1的ClassCastException隐患

方式2.1 目的数组长度大于 0小于原List的 size

    
        String[] arr3 = new String[2];
        //长度不够,需要复制一个新数组
        arr3 = list1.toArray(arr3);
        
        System.out.println("遍历arr3");
        for (String string : arr3) {
            System.out.println(string);
        }
        

** 由于数组长度小于List长度,为了能把集合中的元素放入数组,这种方式会重新创建大小等于 size 的数组(复制一个长度为size的新数组),频繁操作会增加 GC 负担。其对应源码为:**

if (a.length < size)
   return (T[]) Arrays.copyOf(elementData, size, a.getClass());

方式2.2 目的数组长度大于 0大于原List的 size

    
        String[] arr4 = new String[5];
        //目的数组长度大于原List长度
        list1.toArray(arr4);
        
        System.out.println("遍历arr4");
        for (String string : arr4) {
            System.out.println(string);
        }
        

由于数组长度小于List长度,一方面浪费空间,另一方面List size 对应的位置只能插入 null 值,存在 Null指针异常 隐患。其对应源码为:


 if (a.length > size)
    a[size] = null;

方式2.3 目的数组长度等于 0,动态创建与原List size 相同长度的数组

    
    String[] arr2 = list1.toArray(new String[0]);
    System.out.println("遍历arr2");
        for (String string : arr2) {
            System.out.println(string);
        }
        

不多不少,直接挨个复制,这是性能最好的方式。其对应源码为:

System.arraycopy(elementData, 0, a, 0, size);

结语:即便是很常见,看起来很简单的集合操作,不同的实现方式也会有细微的差别,并且可能在生产环境中会对性能产生不小的影响

 

分享到:
评论

相关推荐

    java 数组转list list转数组 list数组互转

    java 数组转list list转数组 list数组互转 java8 代码示例

    java8 list 转数组

    list转数组

    java List和数组相互转换方法-list集合转数组.md

    list转数组

    list转数组(Java+Python)

    list转数组

    list转数组.txt

    list转数组

    list转数组等各种类型互相转换代码

    list转数组

    list转数组.docx

    本文主要讨论了三种将list转换为数组以及数组转换为List的方法,并分析了它们的特点和适用场景。 一、最常见方式:Arrays.asList() 这种方法简单易用,但并不总是最佳选择。通过`Arrays.asList(strArray)`可以直接...

    java遍历list集合3种方式和性能对比

    在Java编程中,遍历List集合是常见的操作,有多种方式可以实现这一功能。下面将详细探讨三种遍历List集合的方法及其性能差异。 1. 使用`Iterator`遍历: ```java List list = new ArrayList(); // 添加元素 for ...

    关于Java中List对象的分页思想-按10个或者n个数对list进行分组

    Java中List对象的分页思想是一种常用的数据处理技术,通过将一个大的List对象分割成多个小的List对象,每个小的List对象包含一定数量的元素,例如10个或n个。这种技术可以用于解决大规模数据的处理问题,例如批量...

    java XML转成LIST可以转成指定的类数组

    在Java编程中,XML(eXtensible Markup Language)是一种常用的数据交换格式,它结构清晰、易于阅读,常用于存储和传输数据。当处理XML文件时,有时我们需要将其内容转换为Java对象,如List,以便于操作和处理。本篇...

    比较Java数组和各种List的性能小结

    在Java编程中,数组和List接口的实现(如ArrayList、LinkedList和Vector)是两种常见的数据结构,它们各自具有不同的特点和性能。这篇文章将探讨这些结构在随机访问、迭代、插入和删除操作上的性能差异。 首先,...

    java List 深度复制方法

    如果List中的元素是基本类型,这种复制方式是没问题的,但如果元素是对象,修改复制后的对象会影响到原始对象,因为它们共享同一份引用。 为了实现深复制,我们需要创建一个新的List,并逐个复制原始List中的每个...

    java list和xml互转例子

    总之,Java List与XML之间的转换是数据交换和持久化的重要手段,而dom4j库提供了一种方便的方式来实现这种转换。通过熟练掌握这些概念和方法,开发者可以更好地在Java应用程序中处理结构化的数据。

    java 中如何从LIST 对象取值

    Java标准库提供了几种实现`List`接口的类,如`ArrayList`、`LinkedList`和`Vector`等。其中,`ArrayList`是最常用的实现之一,它基于动态数组实现,提供随机访问元素的快速性能。 ### 二、从List中取值 #### 2.1 ...

    Java编程实现数组转成list及list转数组的方法

    Java编程实现数组转成list及list转数组的方法是Java编程中的一种常见操作。数组和List都是Java中常用的数据结构,数组是固定大小的数据结构,而List是可变大小的数据结构。在实际开发中,我们经常需要将数组转换为...

    java List中对象多属性排序及各属性排序设置

    本文将深入探讨如何在Java的List中对包含多个属性的对象进行排序,并且支持动态设置每个属性的排序方式。这个功能的实现是通过泛型和自定义比较器(Comparator)来完成的,对于复杂的数据排序需求具有很高的灵活性。...

    《partner4java 讲述 java基础》之第一步:list 、set 、map 粗浅性能对比分析 - java相关技术(partner4java专栏)

    《partner4java 讲述 java基础》之第一步:list 、set 、map 粗浅性能对比分析 - java相关技术(partner4java专栏)

    java for循环的几种写法

    "java for 循环的几种写法" 在 Java 编程语言中,for 循环是一种非常常用的循环语句,用于遍历数组、Collection 等类型的对象。在 J2SE 1.5 中,Java 引入了一种新的 for 循环语法,称为“增强的 for 循环”或...

    java中list排序

    Java 中 List 排序 Java 中 List 排序是指在数据库中查出来的列表中对不同的字段重新排序。一般的做法都是使用排序的字段,重新到数据库中查询。如果不到数据库查询,直接在第一次查出来的 List 中排序,无疑会提高...

Global site tag (gtag.js) - Google Analytics