当我们可以使用 Set 来添加唯一值时,为什么还要使用 ArrayList?
我找到了使用以下方法添加唯一项的有效代码:
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 完成相同的工作。这会帮助我不用担心检查该值是否已存在于列表中。为什么使用哈希集不是一种有效的方法?
I found an efficient code for adding unique items using the below approach:
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);
}
I could have done the same work using a HashSet instead of using an ArrayList. That would have helped me by not worring to check if the value already existed in the list. Why is using a Hashset not an efficient approach?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
HashSet
不实现List
接口。Set
中的值没有索引。我们无法从Set
获取值。因此,如果您只需要存储唯一值,那么您可以安全地使用
Set
实现。如果您需要保持插入顺序,或者需要List
实现的任何其他功能和唯一性,请使用问题中的方法:装饰现有的List< /code> 实现并添加拒绝重复的功能。
您询问了效率:
ArrayList
由数组支持并且速度相当快。但是contains()
的时间复杂度是 O(n) - 为了迭代,我们在最坏情况下查看了每个元素。HashSet
或多或少是一个完整的HashMap
的装饰器,与array
相比稍微重一些。但是contains
的时间复杂度是 O(1) - 检查是在恒定时间内完成的,无论地图中有多少项。如果你只是想迭代 - 一个专门的
List
实现应该稍微快一些 - 迭代的时间复杂度都是 O(n) (毫不奇怪),但是从数组读取比从数组读取更容易一张地图。A
HashSet
does not implement theList
interface. And the values in aSet
are not indexed. We can't get value from aSet
.So if you just need a storage for unique values, then you can safely use a
Set
implementation. If you need to keep insertion order or if you need any other functionality ofList
implementations and uniqueness, then use the method from your question: decorate an existingList
implementation and add functionality to reject duplicates.You asked about efficiency:
ArrayList
is backed by an array and pretty fast. But the time complexity forcontains()
is O(n) - to iterate we have look at each and every element in worst case.HashSet
is more or less a decorator of a full blownHashMap
, somewhat heavier compared to anarray
. But the time complexity forcontains
is O(1) - the check is done in constant time, regardless how many items are inside the map.If you just want to iterate - a specialized
List
implementation should be slightly faster - both have a time complexity of O(n) for the iteration (no surprise) but reading from an array is easier then reading from a Map.实际上,
HashSet
是一种比ArrayList
更好的方法。对于HashSet
,代码的运行时间为 O(n),对于ArrayList
,代码的运行时间为 O(n²)。但是,需要记住一件事:
HashSet
中的元素不按任何特定顺序保存。如果您想保持顺序并快速查找,请使用LinkedHashSet
。 (不过,一切都是有代价的;在本例中,LinkedHashSet
比HashSet
使用更多的内存。)Actually,
HashSet
is a much better approach thanArrayList
. Your code runs in O(n) forHashSet
, and O(n²) forArrayList
.But, one thing to keep in mind: elements in
HashSet
are not kept in any particular order. If you want to keep order and have fast lookups, useLinkedHashSet
. (Everything has a cost, though; in this case,LinkedHashSet
uses more memory thanHashSet
.)这是。你的问题的前提是有缺陷的。
使用 guava 会更简单:
Set set = Sets.newTreeSet(values) ;
//或者HashSetIt is. The premise to your question is flawed.
Use guava and it's easier:
Set set = Sets.newTreeSet( values );
//or HashSet