views:

124

answers:

6
Set<Type> union = new HashSet<Type>(s1);
union.addAll(s2);

AND

Set <Type> union = new HashSet<Type>();
union.addAll(s1);
union.addAll(s2);
+1  A: 

Programmatically or logically?

Cause at the end you end up with the same collection.

Savvas Dalkitsis
+2  A: 

The difference here is much less than your previous question.
The first way should be faster because the original Set will not have to grow as much.

The way you may want to do this is:

Set<Type> union = new HashSet<Type>(s1.size() + s2.size());
union.addAll(s1);
union.addAll(s2);

That way you won't have to resize the new Set at all. (Even though you may have some extra space)

jjnguy
A: 

The first version could be a bit more efficient, because it allocates enough room to contain the elements of s1.

akappa
+1  A: 

I would go with the second form because it is clearer to read. It is easier to see that this is adding two things to the Set because it is explicit. Using two separate ways to put things in the Set obfuscates the fact that the same operation is being done twice.

Kevin Panko
A: 

From the Java 6 source code, we can see that the constructor actually calls addAll once it has initialised the sets size:

public HashSet(Collection<? extends E> c) {
    map = new HashMap<E,Object>(Math.max((int) (c.size()/.75f) + 1, 16));
    addAll(c);
}

Note that this adds at least 1/3 extra capacity, so may be good enough if s2 is small or you are expecting a fair number of intersecting values in the two sets.

Otherwise, all of the other answers make sense!

paulcm
A: 

It depends on the size of your two sets.

(Method 1)
The first way is to say:

Set union = new HashSet();
union.addAll(s1);
union.addAll(s2);

That requires 3 statements, and is not guaranteed to initially be large enough to hold all of your elements. The default backing store is 16 elements. If you have more than 16 elements between s1 and s2, calling the constructor without parameters will be less efficient, because it will have to create a new backing store that is large enough to hold both s1 and s2.

(Method 2)
If you say:

Set union = new HashSet(s1.size() + s2.size());
union.addAll(s1);
union.addAll(s2);

You will be guaranteed to have a set that will hold all of your items, but that also requires 3 statements.

(Method 3)
If you create a new HashSet with a Set, it allocates twice the size of that set. (Java api link) So, if s1 is larger than s2, you get the same effect by saying:

Set union = new HashSet(s1);
union.addAll(s2);

And you only need 2 statements.

If you know ahead of time which set will be larger, use method #3, but if you do not, use method #2.

Matt Poush
The statement about collection allocating to double the size of HashSet is only true for Java version 1.3.1 and older. If you are using 1.4.2 or newer, method #2 is likely the best in most situations.
Matt Poush