List和Set之间的性能和内存分配比较

时间:2012-05-29 12:44:38

标签: java list collections set

我想知道List和Set在性能,内存分配和可用性方面的比较。

如果我没有要求在对象列表中保持唯一性,则既不需要维护插入顺序,我可以交替使用ArrayList和SortedSet / HashSet吗? 直接使用Collections类而不是list / set吗?

会不会很好

P.S。我也不需要列表或设置java提供的特定功能。 我只使用List / Set而不是Array,因为它们可以在没有额外编程工作的情况下动态增长。

6 个答案:

答案 0 :(得分:69)

对于相同数量的元素,

HashSet消耗的内存大约是ArrayList的5.5倍(尽管它们仍然是线性的),并且迭代速度明显较慢(尽管具有相同的渐近线);快速谷歌搜索建议HashSet迭代与ArrayList相比减少2-3倍。

如果您不关心contains的唯一性或效果,请使用ArrayList

答案 1 :(得分:43)

如果您不关心排序,并且不删除元素,那么它实际上归结为您是否需要在此数据结构中查找元素,以及您需要多快查找这些元素。

HashSet中按值查找元素是O(1)。在ArrayList中,它是O(n)

如果你只是使用容器来存储一堆独特的对象,并在最后(以任何顺序)迭代它们,那么可以说ArrayList是更好的选择,因为它更简单,更经济。 / p>

答案 2 :(得分:2)

如果您只打算添加元素并稍后迭代它们,那么最好的选择是ArrayList,因为它最接近您要替换的数组。它比LinkedList或任何Set实现具有更高的内存效率,具有快速插入,迭代和随机访问。

答案 3 :(得分:1)

如果要进行比较,则使用下划线散列算法在List和Set,Set之间进行搜索会更好。

对于列表,在最坏的情况下,包含将搜索到最后。 对于Set,由于哈希和存储桶,它将仅搜索子集。

示例用例: 将1到100_000整数加到ArrayList和HashSet中。 在ArrayList和HashSet中搜索每个整数。

设置将花费9毫秒,而列表将花费16232秒。

private static void compareSetvsList(){
    List<Integer> list = new ArrayList<>() ;
    Set<Integer> set = new HashSet<>() ;

    System.out.println("Setting values in list and set .... ");
    int counter = 100_000  ;

    for(int i =0 ; i< counter ; i++){            
        list.add(i);
        set.add(i);
    }

    System.out.println("Checking time .... ");
    long l1 = System.currentTimeMillis();
    for(int i =0 ; i< counter ; i++) list.contains(i);

    long l2 = System.currentTimeMillis();
    System.out.println(" time taken for list : "+ (l2-l1));

    for(int i =0 ; i< counter ; i++)set.contains(i);

    long l3 = System.currentTimeMillis();
    System.out.println(" time taken for set : "+ (l3-l2));

    //      for 10000   time taken for list : 123        time taken for set : 4
    //      for 100000  time taken for list : 16232          time taken for set : 9
    //      for 1000000 time taken for list : hung       time taken for set : 26

}

答案 4 :(得分:0)

如果您没有要求在集合中添加唯一元素,只需使用ArrayList,除非您有非常具体的需求。

如果您要求集合中只有唯一的元素,请使用HashSet,除非您有非常具体的需求。

关于SortedSet(以及它的实现者TreeSet),根据JavaDoc:

  

进一步提供其元素的总排序的集合。元素按照其自然顺序排序,或者通过在排序集创建时提供的比较器进行排序。

意味着它针对非常具体的用例,当元素总是以set排序时,通常不需要。

答案 5 :(得分:0)

如果您需要经常使用HashSet,请使用.contains(T)

示例:

private static final HashSet<String> KEYWORDS = Stream.of(new String[]{"if", "do", "for", "try", "while", "break", "return"}).collect(Collectors.toCollection(HashSet::new));

public boolean isKeyword(String str) {
     return KEYWORDS.contains(str);
}