05-集合框架区别以及性能测试

一、区别

这一块属于面试比较容易遇到的 : 

  针对Collection下的集合的区别

    Collection 

        |- List (接口)顺序是List 最重要的特性 他可以保证元素可以按照规定的顺序排列

             |- ArrayList  底层是有一个数组实现的 允许对元素的快速访问,用来替换原来的Vector  数组的缺点是元素之间不能有间隔,当数组大小不够时,就需要拓展其存储

                               能力,将现有的数组元素复制到新的存储空间 因此在ArrayList中间位置插入数据或者删除数据的时候就涉及到了数组元素的复制、移动等相对消耗性

                               能的操作,因此通常情况下 ArrayList用来对数据的遍历和查找,不适合插入和删除等操作。

             |- LinkedList 用链表结构存储数据,能快速的插入和删除 但是不适合数据的遍历 也提供了addFirst(),addLast(),getFirst(),getLast(),removeFirst() 以及

                                removeLast()等方法 也可以将LinkedList当作一个规格的队列或者双向队列使用  提供push() pop() 方法 可当作堆栈使用

             |- Vector      底层是数组的实现 不同的是它支持线程的同步,即某一时刻只有一个线程能够写Vector,避免多线程同时写而引起的不一致性,但实现同步需要很高的

              花费,因此,访问它比访问ArrayList慢    

             -- ListIterator  专门为List结合提供的迭代器 利用它可在一个列表里朝两个方向遍历,同时插入和删除位于列表中部的元素(同样地,只建议对LinkedList 这样做)

        |- Set (接口) 添加到Set 的每个元素都必须是独一无二的,否则Set 就不会添加重复的元素

              |-HashSet  用于非常小的以外的所有Set  无序的集合

              |-ArraySet 由一个数组后推得到的Set。面向非常小的Set 设计,特别是那些需要频繁创建和删除的。对于小Set,与HashSet 相比,ArraySet 创建和反复所需付

            出的代价都要小得多。但随着Set 的增大,它的性能也会大打折扣。 

              |-TreeSet  由一个“红黑树”后推得到的顺序Set  有序的集合

二、性能测试

      工具类: 

//: Collection1.java
// Things you can do with all Collections
package c08.newcollections;

import java.util.*;
public class Collection1 {
    // Fill with 'size' elements, start

    // counting at 'start':
    public static Collection fill(Collection c, int start, int size) {
        for (int i = start; i < start + size; i++)
            c.add(Integer.toString(i));
        return c;
    }

    // Default to a "start" of 0:
    public static Collection fill(Collection c, int size) {
        return fill(c, 0, size);
    }

    // Default to 10 elements:
    public static Collection fill(Collection c) {
        return fill(c, 0, 10);
    }

    // Create & upcast to Collection:
    public static Collection newCollection() {
        return fill(new ArrayList());
        // ArrayList is used for simplicity, but it's
        // only seen as a generic Collection
        // everywhere else in the program.
    }

    // Fill a Collection with a range of values:
    public static Collection newCollection(int start, int size) {
        return fill(new ArrayList(), start, size);
    }

    // Moving through a List with an iterator:
    public static void print(Collection c) {
        for (Iterator x = c.iterator(); x.hasNext();)
            System.out.print(x.next() + " ");
        System.out.println();
    }

     
} // /:~

     2.1 List 测试

//: ListPerformance.java
// Demonstrates performance differences in Lists
package c08.newcollections;

import java.util.*;

public class ListPerformance {
    private static final int REPS = 100;

    private abstract static class Tester {
        String name;
        int size; // Test quantity

        Tester(String name, int size) {
            this.name = name;
            this.size = size;
        }

        abstract void test(List a);
    }

    private static Tester[] tests = { new Tester("get", 300) {
        void test(List a) {
            for (int i = 0; i < REPS; i++) {  
                for (int j = 0; j < a.size(); j++)
                    a.get(j);
            }
        }
    },

    new Tester("iteration", 300) {
        void test(List a) {
            for (int i = 0; i < REPS; i++) {
                Iterator it = a.iterator();
                while (it.hasNext())
                    it.next();
            }
        }
    }, new Tester("insert", 1000) {
        void test(List a) {
            int half = a.size() / 2;
            String s = "test";
            ListIterator it = a.listIterator(half);
            for (int i = 0; i < size * 10; i++)
                it.add(s);
        }
    }, new Tester("remove", 5000) {
        void test(List a) {
            ListIterator it = a.listIterator(3);
            while (it.hasNext()) {
                it.next();
                it.remove();
            }
        }
    }, };

    public static void test(List a) {
        // A trick to print out the class name:
        System.out.println("Testing " + a.getClass().getName());
        for (int i = 0; i < tests.length; i++) {
            Collection1.fill(a, tests[i].size);
            System.out.print(tests[i].name);
            long t1 = System.currentTimeMillis();
            tests[i].test(a);
            long t2 = System.currentTimeMillis();
            System.out.println(": " + (t2 - t1));
        }
    }

    public static void main(String[] args) {
        test(new ArrayList());
        test(new LinkedList());
    }
} // /:~

  执行的结果: 

   

Testing java.util.ArrayList
get: 4
iteration: 5
insert: 9
remove: 91
Testing java.util.LinkedList
get: 13
iteration: 5
insert: 3
remove: 6

    2.2 Set测试 

      

//: SetPerformance.java
package c08.newcollections;

import java.util.*;

public class SetPerformance {
    private static final int REPS = 200;

    private abstract static class Tester {
        String name;

        Tester(String name) {
            this.name = name;
        }

        abstract void test(Set s, int size);
    }

    private static Tester[] tests = { new Tester("add") {
        void test(Set s, int size) {
            for (int i = 0; i < REPS; i++) {
                s.clear();
                Collection1.fill(s, size);
            }
        }
    }, new Tester("contains") {
        void test(Set s, int size) {
            for (int i = 0; i < REPS; i++)
                for (int j = 0; j < size; j++)
                    s.contains(Integer.toString(j));
        }
    }, new Tester("iteration") {
        void test(Set s, int size) {
            for (int i = 0; i < REPS * 10; i++) {
                Iterator it = s.iterator();
                while (it.hasNext())
                    it.next();
            }

        }
    }, };

    public static void test(Set s, int size) {
        // A trick to print out the class name:
        System.out.println("Testing " + s.getClass().getName() + " size "
                + size);
        Collection1.fill(s, size);
        for (int i = 0; i < tests.length; i++) {
            System.out.print(tests[i].name);
            long t1 = System.currentTimeMillis();
            tests[i].test(s, size);
            long t2 = System.currentTimeMillis();
            System.out.println(": " + ((double) (t2 - t1) / (double) size));
        }
    }

    public static void main(String[] args) {
        // Small:
        test(new TreeSet(), 10);
        test(new HashSet(), 10);
        // Medium:
        test(new TreeSet(), 100);
        test(new HashSet(), 100);
        // Large:
        test(new HashSet(), 1000);
        test(new TreeSet(), 1000);
    }
} // /:~

执行的结果: 

Testing java.util.TreeSet size 10
add: 0.8
contains: 0.2
iteration: 0.8
Testing java.util.HashSet size 10
add: 0.3
contains: 0.1
iteration: 0.7
Testing java.util.TreeSet size 100
add: 0.12
contains: 0.06
iteration: 0.07
Testing java.util.HashSet size 100
add: 0.06
contains: 0.02
iteration: 0.09
Testing java.util.HashSet size 1000
add: 0.031
contains: 0.026
iteration: 0.082
Testing java.util.TreeSet size 1000
add: 0.127
contains: 0.077
iteration: 0.083
contains 随机访问  add  添加数据  方面 TreeSet 不如 HashSet    数据量大的时候优先使用HashSet

 

    2.3 Map测试 

 
//: MapPerformance.java
// Demonstrates performance differences in Maps
package c08.newcollections;

import java.util.*;

public class MapPerformance {
    private static final int REPS = 200;

    public static Map fill(Map m, int size) {
        for (int i = 0; i < size; i++) {
            String x = Integer.toString(i);
            m.put(x, x);
        }
        return m;
    }

    private abstract static class Tester {
        String name;

        Tester(String name) {
            this.name = name;
        }

        abstract void test(Map m, int size);
    }

    private static Tester[] tests = { new Tester("put") {
        void test(Map m, int size) {
            for (int i = 0; i < REPS; i++) {
                m.clear();
                fill(m, size);
            }
        }
    }, new Tester("get") {
        void test(Map m, int size) {
            for (int i = 0; i < REPS; i++)
                for (int j = 0; j < size; j++)
                    m.get(Integer.toString(j));
        }
    }, new Tester("iteration") {
        void test(Map m, int size) {
            for (int i = 0; i < REPS * 10; i++) {
                Iterator it = m.keySet().iterator();
                while (it.hasNext())
                    it.next();
            }
        }
    }, };

    public static void test(Map m, int size) {
        // A trick to print out the class name:
        System.out.println("Testing " + m.getClass().getName() + " size "
                + size);

        fill(m, size);
        for (int i = 0; i < tests.length; i++) {
            System.out.print(tests[i].name);
            long t1 = System.currentTimeMillis();
            tests[i].test(m, size);
            long t2 = System.currentTimeMillis();
            System.out.println(": " + ((double) (t2 - t1) / (double) size));
        }
    }

    public static void main(String[] args) {
        // Small:
        test(new Hashtable(), 10);
        test(new HashMap(), 10);
        test(new TreeMap(), 10);
        // Medium:
        test(new Hashtable(), 100);
        test(new HashMap(), 100);
        test(new TreeMap(), 100);
        // Large:
        test(new HashMap(), 1000);
        test(new Hashtable(), 1000);
        test(new TreeMap(), 1000);
    }
} // /:~  
执行结果: 
Testing java.util.Hashtable size 10
put: 0.5
get: 0.1
iteration: 0.7
Testing java.util.HashMap size 10
put: 0.3
get: 0.1
iteration: 0.8
Testing java.util.TreeMap size 10
put: 0.6
get: 0.1
iteration: 0.5
Testing java.util.Hashtable size 100
put: 0.03
get: 0.02
iteration: 0.09
Testing java.util.HashMap size 100
put: 0.06
get: 0.02
iteration: 0.09
Testing java.util.TreeMap size 100
put: 0.08
get: 0.05
iteration: 0.07
Testing java.util.HashMap size 1000
put: 0.029
get: 0.027
iteration: 0.079
Testing java.util.Hashtable size 1000
put: 0.031
get: 0.029
iteration: 0.08
Testing java.util.TreeMap size 1000
put: 0.16
get: 0.086
iteration: 0.091
 

当我们使用Map 时,首要的选择应该是HashMap。只有在极少数情况下才需要考虑其他方法  

  TreeMap 提供了出色的put()以及遍历时间,但get()的性能并不佳

 

               

原文地址:https://www.cnblogs.com/liaokailin/p/3673606.html