我找到了一个使用以下方法添加唯一项目的有效代码:
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不是一种有效的方法?
答案 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)