一、简介

ListSet 都继承 Collection 接口,Map 不是。

  • List:元素有序存储,元素可重复,取出来的顺序可能和放入的顺序不同,支持for循环和迭代器遍历;

  • Set:元素无序存储,且唯一,不能包含重复的元素,不支持for循环遍历,支持迭代器遍历;

  • Map:元素无序存储,key值唯一不能重复,value值可重复,支持迭代器遍历;

List、Set、Map实现类

  • ListArrayListLinkedListVector

  • SetHashSetTreeSetLinkedHashSet

  • MapHashMapTreeMapHashTableLinkedHashMap

线程安全 / 线程不安全

  • 线程安全:Vector、HashTable

  • 线程不安全:ArrayList、LinkedList、HashSet、LinkedHashSet、HashMap、TreeMap、LinkedHashMap

下面我们只拿出 ArrayListLinkedListHashSetHashMapLinkedHashMap 来讲解遍历方式以及遍历性能比较。



二、遍历方式

1、ArrayList遍历方式

ArrayList有三种遍历方式:for循环遍历foreach循环遍历Iterator迭代器遍历


(1)for循环遍历

ArrayList<String> lists = new ArrayList<String>();
for(int i=0;i<lists.size();i++){
	String line = lists.get(i);
}

(2)foreach循环遍历

ArrayList<String> lists = new ArrayList<String>();
for(String str : lists){
	String line = str;
}

(3)Iterator迭代器遍历

ArrayList<String> lists = new ArrayList<String>();
Iterator<String> iterator = lists.iterator();
while (iterator.hasNext()){
	String line = iterator.next();
}

2、LinkedList遍历方式

LinkedList有三种遍历方式:for循环遍历foreach循环遍历Iterator迭代器遍历


(1)for循环遍历

LinkedList<String> lists = new LinkedList<String>();
for(int i=0;i<lists.size();i++){
	String line = lists.get(i);
}

(2)foreach循环遍历

LinkedList<String> lists = new LinkedList<String>();
for(String str : lists){
	String line = str;
}

(3)Iterator迭代器遍历

LinkedList<String> lists = new LinkedList<String>();
Iterator<String> iterator = lists.iterator();
while (iterator.hasNext()){
	String line = iterator.next();
}

3、HashSet遍历方式

HashSet有两种遍历方式:foreach循环遍历Iterator迭代器遍历


(1)foreach循环遍历

HashSet<String> hashSets = new HashSet<String>();
for(String str : hashSets){
	String line = str;
}

(2)Iterator迭代器遍历

HashSet<String> hashSets = new HashSet<String>();
Iterator<String> iterator = hashSets.iterator();
while (iterator.hasNext()){
	String line = iterator.next();
}

4、HashMap遍历方式

HashMap有三种遍历方式:keySet循环遍历entrySet遍历Iterator迭代器遍历

下面我们只讲解 entrySet遍历Iterator迭代器遍历


(1)entrySet遍历

HashMap<String, String> hashMaps = new HashMap<String, String>();
for(Map.Entry<String, String> entry : hashMaps.entrySet()){
	String line = entry.getKey();
}

(2)Iterator迭代器遍历

HashMap<String, String> hashMaps = new HashMap<String, String>();
Iterator iterator = hashMaps.entrySet().iterator();
while (iterator.hasNext()){
	Map.Entry<String, String> entry = (Map.Entry<String, String>)iterator.next();
	String line = entry.getKey();
}

5、LinkedHashMap遍历方式

LinkedHashMap有三种遍历方式:keySet循环遍历entrySet遍历Iterator迭代器遍历

下面我们只讲解 entrySet遍历Iterator迭代器遍历


(1)entrySet遍历

LinkedHashMap<String, String> linkedHashMaps = new LinkedHashMap<String, String>();
for(Map.Entry<String, String> entry : linkedHashMaps.entrySet()){
	String line = entry.getKey();
}

(2)Iterator迭代器遍历

LinkedHashMap<String, String> linkedHashMaps = new LinkedHashMap<String, String>();
Iterator iterator = linkedHashMaps.entrySet().iterator();
while (iterator.hasNext()){
	Map.Entry<String, String> entry = (Map.Entry<String, String>)iterator.next();
	String line = entry.getKey();
}

三、性能比较

不同数量级的性能差异是比较大的,下面我们分别在30、100、1000、10000、100000数量级进行性能比较。

完整代码如下:

package com.example.springbootdemo.util;

import java.util.*;

public class Test {

    public static void main(String[] args) {
        compare();
    }

    private static ArrayList<String> lists = new ArrayList<String>();
    private static LinkedList<String> linkedLists = new LinkedList<String>();

    private static HashSet<String> hashSets = new HashSet<String>();

    private static HashMap<String, String> hashMaps = new HashMap<String, String>();
    private static LinkedHashMap<String, String> linkedHashMaps = new LinkedHashMap<String, String>();

    private static void compare(){
        compareInit(100000);
        compare1();
    }

    private static void compareInit(int count){
        lists.clear();
        linkedLists.clear();
        hashMaps.clear();
        hashSets.clear();
        linkedHashMaps.clear();
        String str = "abcdefg_";
        String one = "";
        for(int i=0;i<count;i++){
            one = str + i;
            lists.add(one);
            linkedLists.add(one);
            hashSets.add(one);
            hashMaps.put(one, one);
            linkedHashMaps.put(one, one);
        }
    }

    private static final String listFor               = "ArrayList for          duration";
    private static final String listForeach           = "ArrayList foreach      duration";
    private static final String listIterator          = "ArrayList Iterator     duration";
    private static final String linkedListFor         = "LinkedList for         duration";
    private static final String linkedListForeach     = "LinkedList foreach     duration";
    private static final String linkedListIterator    = "LinkedList Iterator    duration";
    private static final String hashSetForeach        = "HashSet foreach        duration";
    private static final String hashSetIterator       = "HashSet Iterator       duration";
    private static final String hashMapEntry          = "HashMap entry          duration";
    private static final String hashMapIterator       = "HashMap Iterator       duration";
    private static final String linkedHashMapEntry    = "LinkedHashMap entry    duration";
    private static final String linkedHashMapIterator = "LinkedHashMap Iterator duration";

    private static void compare1(){
        for(int i=0;i<5;i++){
            System.out.println("------------------------------");
            listOne();
            listTwo();
            listThree();
            linkedListOne();
            linkedListTwo();
            linkedListThree();
            hashSetOne();
            hashSetTwo();
            hashMapOne();
            hashMapTwo();
            linkedHashMapOne();
            linkedHashMapTwo();
            System.out.println();
        }
    }

    private static void listOne(){
        String line = "";
        long start = System.nanoTime();
        for(int i=0;i<lists.size();i++){
            line = lists.get(i);
        }
        long end = System.nanoTime();
        print(start, end, listFor);
    }

    private static void listTwo(){
        String line = "";
        long start = System.nanoTime();
        for(String str : lists){
            line = str;
        }
        long end = System.nanoTime();
        print(start, end, listForeach);
    }

    private static void listThree(){
        String line = "";
        long start = System.nanoTime();
        Iterator<String> iterator = lists.iterator();
        while (iterator.hasNext()){
            line = iterator.next();
        }
        long end = System.nanoTime();
        print(start, end, listIterator);
    }

    private static void linkedListOne(){
        String line = "";
        long start = System.nanoTime();
        for(int i=0;i<linkedLists.size();i++){
            line = linkedLists.get(i);
        }
        long end = System.nanoTime();
        print(start, end, linkedListFor);
    }

    private static void linkedListTwo(){
        String line = "";
        long start = System.nanoTime();
        for(String str : linkedLists){
            line = str;
        }
        long end = System.nanoTime();
        print(start, end, linkedListForeach);
    }

    private static void linkedListThree(){
        String line = "";
        long start = System.nanoTime();
        Iterator<String> iterator = linkedLists.iterator();
        while (iterator.hasNext()){
            line = iterator.next();
        }
        long end = System.nanoTime();
        print(start, end, linkedListIterator);
    }

    private static void hashSetOne(){
        String line = "";
        long start = System.nanoTime();
        for(String str : hashSets){
            line = str;
        }
        long end = System.nanoTime();
        print(start, end, hashSetForeach);
    }

    private static void hashSetTwo(){
        String line = "";
        long start = System.nanoTime();
        Iterator<String> iterator = hashSets.iterator();
        while (iterator.hasNext()){
            line = iterator.next();
        }
        long end = System.nanoTime();
        print(start, end, hashSetIterator);
    }

    private static void hashMapOne(){
        String line = "";
        long start = System.nanoTime();
        for(Map.Entry<String, String> entry : hashMaps.entrySet()){
            line = entry.getKey();
        }
        long end = System.nanoTime();
        print(start, end, hashMapEntry);
    }

    private static void hashMapTwo(){
        String line = "";
        long start = System.nanoTime();
        Iterator iterator = hashMaps.entrySet().iterator();
        while (iterator.hasNext()){
            Map.Entry<String, String> entry = (Map.Entry<String, String>)iterator.next();
            line = entry.getKey();
        }
        long end = System.nanoTime();
        print(start, end, hashMapIterator);
    }

    private static void linkedHashMapOne(){
        String line = "";
        long start = System.nanoTime();
        for(Map.Entry<String, String> entry : linkedHashMaps.entrySet()){
            line = entry.getKey();
        }
        long end = System.nanoTime();
        print(start, end, linkedHashMapEntry);
    }

    private static void linkedHashMapTwo(){
        String line = "";
        long start = System.nanoTime();
        Iterator iterator = linkedHashMaps.entrySet().iterator();
        while (iterator.hasNext()){
            Map.Entry<String, String> entry = (Map.Entry<String, String>)iterator.next();
            line = entry.getKey();
        }
        long end = System.nanoTime();
        print(start, end, linkedHashMapIterator);
    }

    private static void print(long start, long end, String tip){
        System.out.println(tip + " = [" + ((double)((end - start)/1000))/1000 + "]ms");
    }
}

我们经过多轮测试,取相对合理的结果进行展示,单位为:毫秒(ms)

type30100100010000100000
ArrayList - for0.0030.0080.0570.5190.674
ArrayList - foreach0.0120.0090.0650.4950.632
ArrayList - Iterator0.0100.0070.0740.4990.62
LinkedList - for0.0310.0390.49864.04416374.155
LinkedList - foreach0.0110.0120.0750.5261.989
LinkedList - Iterator0.0080.0080.0680.5181.98
HashSet - foreach0.0090.0250.0870.7541.955
HashSet - Iterator0.0050.0110.0930.731.931
HashMap - entrySet0.0120.0250.0920.9552.007
HashMap - Iterator0.0090.0150.0820.9052.0
LinkedHashMap - entrySet0.0160.0250.090.7192.596
LinkedHashMap - Iterator0.0120.0130.0780.7042.46

单个类型不同遍历方式性能比较总结:

  • ArrayList:三种遍历方式性能差距不大,数量级较小时,for循环遍历更优,数量级较大时,Iterator迭代器遍历方式性能更优;

  • LinkedList:三种遍历方式中for循环遍历性能最差,其他两种方式性能差距比较小,但是Iterator迭代器遍历方式性能更优;

  • HashSet:两种遍历方式性能差距不大,但是Iterator迭代器遍历方式性能更优;

  • HashMap:两种遍历方式性能差距不大,但是Iterator迭代器遍历方式性能更优;

  • LinkedHashMap:两种遍历方式性能差距不大,但是Iterator迭代器遍历方式性能更优;


整体性能比较总结:

  • 同等数量级,ArrayList的遍历性能更优;
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐