当我们可以使用Set添加唯一值时,为什么我们使用ArrayList?

时间:2011-04-27 04:15:38

标签: java arrays arraylist set

我找到了一个使用以下方法添加唯一项目的有效代码:

int[] values = { -5, -3, -1, 0, 3, 6 };

List<Integer> list=new ArrayList<Integer>();

for(int val : values)

{

   if(!list.contains(val))

   list.add(val);

}

我可以使用HashSet而不是使用ArrayList完成相同的工作。这可以帮助我,不用担心检查列表中是否已存在该值。为什么使用Hashset不是一种有效的方法?

3 个答案:

答案 0 :(得分:4)

HashSet未实现List接口。并且Set中的值未编入索引。我们无法从Set 获得值。

因此,如果您只需要存储唯一值,那么您可以安全地使用Set实现。如果您需要保留插入顺序,或者如果您需要List实现唯一性的任何其他功能,请使用您问题中的方法:装饰现有的List实现并添加拒绝重复的功能。

您询问了效率:ArrayList由数组支持且非常快。但是contains()的时间复杂度是O(n) - 迭代我们在最坏的情况下看每一个元素。

HashSet或多或少是一个完整的HashMap的装饰者,与array相比稍微重一点。但是contains的时间复杂度是O(1) - 无论地图中有多少项,检查都是在恒定时间内完成的。

如果你只是想迭代 - 一个专门的List实现应该稍微快一些 - 迭代的时间复杂度为O(n)(毫不奇怪)但是从数组读取比从一张地图。

答案 1 :(得分:3)

实际上,HashSet是比ArrayList更好的 方法。您的代码在HashSet的O(n)和ArrayList的O(n²)中运行。

但是,要记住一件事:HashSet中的元素不会按任何特定顺序保留。如果您想保持订单快速查找,请使用LinkedHashSet。 (但是一切都有成本;在这种情况下,LinkedHashSet使用的内存比HashSet多。)

答案 2 :(得分:1)

是的。你问题的前提是有缺陷的。

使用guava并且更容易:

Set set = Sets.newTreeSet( values ); //或HashSet