Java collection insertion: Set vs. List

2019-04-06 00:41发布

I'm thinking about filling a collection with a large amount of unique objects. How is the cost of an insert in a Set (say HashSet) compared to an List (say ArrayList)?

My feeling is that duplicate elimination in sets might cause a slight overhead.

7条回答
Bombasti
2楼-- · 2019-04-06 01:22

There is no "duplicate elimination" such as comparing to all existing elements. If you insert into hash set, it's really a dictionary of items by hash code. There's no duplicate checking unless there already are items with the same hash code. Given a reasonable (well-distributed) hash function, it's not that bad.

As Will has noted, because of the dictionary structure HashSet is probably a bit slower than an ArrayList (unless you want to insert "between" existing elements). It also is a bit larger. I'm not sure that's a significant difference though.

查看更多
3楼-- · 2019-04-06 01:23

Java List:

If you don't have such requirement that you have to keep duplicate or not. Then you can use List instead of Set.

List is an interface in Collection framework. Which extends Collection interface. and ArrayList, LinkedList is the implementation of List interface.

When to use ArrayList or LinkedList

ArrayList: If you have such requirement that in your application mostly work is accessing the data. Then you should go for ArrayList. because ArrayList implements RtandomAccess interface which is Marker Interface. because of Marker interface ArrayList have capability to access the data in O(1) time. and you can use ArrayList over LinkedList where you want to get data according to insertion order.

LinkedList: If you have such requirement that your mostly work is insertion or deletion. Then you should use LinkedList over the ArrayList. because in LinkedList insertion and deletion happen in O(1) time whereas in ArrayList it's O(n) time.

Java Set:

If you have requirement in your application that you don't want any duplicates. Then you should go for Set instead of List. Because Set doesn't store any duplicates. Because Set works on the principle of Hashing. If we add object in Set then first it checks object's hashCode in the bucket if it's find any hashCode present in it's bucked then it'll not add that object.

查看更多
何必那么认真
4楼-- · 2019-04-06 01:27

I don't think you can make this judgement simply on the cost of building the collection. Other things that you need to take into account are:

  • Is the input dataset ordered? Is there a requirement that the output data structure preserves insertion order?
  • Is there a requirement that the output data structure is ordered (or reordered) based on element values?
  • Will the output data structure be subsequently modified? How?
  • Is there a requirement that the output data structure is duplicate free if other elements are added subsequently?
  • Do you know how many elements are likely to be in the input dataset?
  • Can you measure the size of the input dataset? (Or is it provided via an iterator?)
  • Does space utilization matter?

These can all effect your choice of data structure.

查看更多
做个烂人
5楼-- · 2019-04-06 01:30

If the goal is the uniqueness of the elements, you should use an implementation of the java.util.Set interface. The class java.util.HashSet and java.util.LinkedHashSet have O(alpha) (close to O(1) in the best case) complexity for insert, delete and contains check.

ArrayList have O(n) for object (not index) contains check (you have to scroll through the whole list) and insertion (if the insertion is not in tail of the list, you have to shift the whole underline array).

You can use LinkedHashSet that preserve the order of insertion and have the same potentiality of HashSet (takes up only a bit more of memory).

查看更多
Fickle 薄情
6楼-- · 2019-04-06 01:38

If you're certain your data will be unique, use a List. You can use a Set to enforce this rule.

Sets are faster than Lists if you have a large data set, while the inverse is true for smaller data sets. I haven't personally tested this claim.

Which type of List?
Also, consider which List to use. LinkedLists are faster at adding, removing elements.

ArrayLists are faster at random access (for loops, etc), but this can be worked around using the Iterator of a LinkedList. ArrayLists are are much faster at: list.toArray().

查看更多
Juvenile、少年°
7楼-- · 2019-04-06 01:47

You're right: set structures are inherently more complex in order to recognize and eliminate duplicates. Whether this overhead is significant for your case should be tested with a benchmark.

Another factor is memory usage. If your objects are very small, the memory overhead introduced by the set structure can be significant. In the most extreme case (TreeSet<Integer> vs. ArrayList<Integer>) the set structure can require more than 10 times as much memory.

查看更多
登录 后发表回答