所有分类
  • 所有分类
  • 未分类

Java之List–创建与遍历的方法

简介

本文介绍Java中List的使用,包括:创建、遍历。

创建

法1:构造 List 后使用 List.add(繁琐)

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

法2:Arrays.asList

下边两种方法的区别见:Java工具类-Arrays的用法 – 自学精灵

List<String> list = Arrays.asList("a", "b");

或者

List<String> list = new ArrayList<>(Arrays.asList("a", "b"));

法3:Stream (JDK8)

List<String> list = Stream.of("a", "b").collect(Collectors.toList()); 

法4:{{}}

List<String> list = new ArrayList<String>() {{
    add("a");
    add("b");
}};

说明

外层的 {} 定义了一个 ArrayList 的匿名内部类。内层的 {} 的定义了一个实例初始化代码块。 这个代码块在初始化内部类时执行。所以这里相当于定义了一个匿名内部类,并使用 add 添加元素来初始化。

{{}} 双括号语法同样可用于初始化 Map 等其他众多类型。

缺点

  1. 使用匿名内部类,会有效率上的损失。当然在大多数情况下,这点效率都是可接受的。
  2. 非静态内部类持有所在外部类的引用,可能造成内存泄漏。见:Java-内存泄露的原因及解决方案(大全) – 自学精灵

法5:google的guava(JDK9)

List<String> list = Lists.newArrayList("one","two","three");

遍历

简介

说明

  • 记录的存取方式有两种:一种是数组方式存储,另一种是链表方式。
  • 对于数组方式存储的记录可以根据其下标找到对应的记录,而链表方式存储(单链表为例)则必须找到其前一个记录的位置才能够找到本记录。
    • 所以:for循环便于访问数组方式存储的记录,比如数组等;而迭代则更适用于链表存储的记录。

法1:for循环

List<Object> list = new ArrayList<>();
for (int i = 0; i < list.size(); i++) {
    Object value = list.get(i);
}

法2:增强for循环

List<Object> list = new ArrayList<>();
for (Object s : list) {
    Object value = s;
}

法3:迭代器(Iterator)

Iterator<Object> iter = list.iterator();
while (iter.hasNext()) {
    Object value = iter.next();
}

 法4:foreach

List<Object> list = new ArrayList<>();
list.forEach(o -> {Object value = o});

实际上,foreach底层也是通过Iterator来遍历,上边的代码反编译之后:

List<Object> list = new ArrayList<>();
for (Iterator iterator = list.iterator(); iterator.hasNext();) {  
    Object value = iterator.next(); 
}

性能

结论

ArrayList:按性能由高到低排序:forEach > Iterator > 增强for > for

LinkedList:按性能由高到低排序: Iterator > 增强for > forEach> for

ArrayList测试

package org.example.a;

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

public class Demo {
    public static void main(String[] args) {
        Object obj = new Object();
        List<Object> list = new ArrayList<>();

        int objCount = 1000;
        for (int i = 0; i < objCount; i++) {
            list.add(obj);
        }

        int testTimes = 5;
        for (int i = 0; i < testTimes; i++) {
            testFor(list);
            testForEnhanced(list);
            testForEach(list);
            testIterator(list);
            System.out.println();
        }
    }

    private static void testFor(List<Object> list) {
        long startTime = 0L;
        long endTime = 0L;
        startTime = System.nanoTime();

        for (int i = 0; i < list.size(); i++) {
            Object o = list.get(i);
        }
        endTime = System.nanoTime();
        System.out.println("for所用时间(ns)      :" + (endTime - startTime));
    }

    private static void testForEnhanced(List<Object> list) {
        long startTime = 0L;
        long endTime = 0L;
        startTime = System.nanoTime();

        for (Object o : list) {
            Object value = o;
        }

        endTime = System.nanoTime();
        System.out.println("增强for所用时间(ns)  :" + (endTime - startTime));
    }

    private static void testForEach(List<Object> list) {
        long startTime = 0L;
        long endTime = 0L;
        startTime = System.nanoTime();

        list.forEach(o->{Object obj = o;});

        endTime = System.nanoTime();
        System.out.println("forEach所用时间(ns)  :" + (endTime - startTime));
    }

    private static void testIterator(List<Object> list) {
        long startTime = 0L;
        long endTime = 0L;
        startTime = System.nanoTime();

        Iterator<Object> iterator = list.iterator();
        while (iterator.hasNext()) {
            Object o = iterator.next();
        }
        endTime = System.nanoTime();
        System.out.println("iterator所用时间(ns) :" + (endTime - startTime));
    }
}

结果

for所用时间(ns)      :619500
增强for所用时间(ns)  :572300
forEach所用时间(ns)  :121775301
iterator所用时间(ns) :34700

for所用时间(ns)      :36799
增强for所用时间(ns)  :36000
forEach所用时间(ns)  :24300
iterator所用时间(ns) :33200

for所用时间(ns)      :41401
增强for所用时间(ns)  :37800
forEach所用时间(ns)  :23799
iterator所用时间(ns) :44100

for所用时间(ns)      :34400
增强for所用时间(ns)  :345101
forEach所用时间(ns)  :24300
iterator所用时间(ns) :31200

for所用时间(ns)      :34299
增强for所用时间(ns)  :33100
forEach所用时间(ns)  :23099
iterator所用时间(ns) :30901

第一次测试:性能由高到低排序: Iterator > 增强for > for > forEach

第二次之后:性能由高到低排序:forEach > Iterator > 增强for > for

原因:

  • java8的foreach预热是jvm级别的,需要预热。
  • 增强for编译之后是基于Iterator的,所以会比直接用Iterator稍微慢一点点。(写一个增强for循环代码,然后反编译,即可发现它是迭代器方式)

LinkedList测试

 将上边测试代码中的ArrayList改为LinkedList,其他不变。

结果:

for所用时间(ns)      :1399300
增强for所用时间(ns)  :1391200
forEach所用时间(ns)  :57331500
iterator所用时间(ns) :44099

for所用时间(ns)      :940200
增强for所用时间(ns)  :38701
forEach所用时间(ns)  :71100
iterator所用时间(ns) :60600

for所用时间(ns)      :976100
增强for所用时间(ns)  :32301
forEach所用时间(ns)  :46000
iterator所用时间(ns) :28700

for所用时间(ns)      :358901
增强for所用时间(ns)  :37100
forEach所用时间(ns)  :42401
iterator所用时间(ns) :29000

for所用时间(ns)      :358100
增强for所用时间(ns)  :30500
forEach所用时间(ns)  :41499
iterator所用时间(ns) :28800
0

评论0

请先

显示验证码
没有账号?注册  忘记密码?

社交账号快速登录