我想知道List和Set在性能,内存分配和可用性方面的比较。
如果我没有要求在对象列表中保持唯一性,则既不需要维护插入顺序,我可以交替使用ArrayList和SortedSet / HashSet吗? 直接使用Collections类而不是list / set吗?
会不会很好P.S。我也不需要列表或设置java提供的特定功能。 我只使用List / Set而不是Array,因为它们可以在没有额外编程工作的情况下动态增长。
答案 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);
}