views:

1001

answers:

6

Hello, I need to create a Set with initial values.

    Set<String> h = new HashSet<String>();
    h.add("a");
    h.add("b");

Is there a way to do it in one command? Thanks

+3  A: 

Until Java 7 - not a very good one. You can use the following syntax, which will create an anonymous class:

Set<String> h = new HashSet<String>() {{
    add("a");
    add("b");
}};
Bozho
Thanks! this is what I needed.
Serg
Note that some consider it a grotesque hack.
Kevin Bourrillion
yes, as I said - not a very good one :)
Bozho
+6  A: 

There are a few ways:

Double brace initialization

This is a technique which creates an anonymous inner class which has an instance initializer which adds Strings to itself when an instance is created:

Set<String> s = new HashSet<String>() {{
    this.add("a");
    this.add("b");
}}

Keep in mind that this will actually create an new subclass of HashSet each time it is used, even though one does not have to explicitly write a new subclass.

A utility method

Writing a method that returns a Set which is initialized with the desired elements isn't too hard to write:

public static newHashSet(String... strings) {
    HashSet<String> set = new HashSet<String>();

    for (String s : strings) {
        set.add(s);
    }
    return set;
}

The above code only allows for a use of a String, but it shouldn't be too difficult to allow the use of any type using generics.

Use a library

Many libraries have a convenience method to initialize collections objects.

For example, Google Collections has a Sets.newHashSet(T...) method which will populate a HashSet with elements of a specific type.

coobird
GoogleCollections also has `ImmutableSet.of(T...)`. Most of the time when doing this you don't need to change the set again later, and in that case, using an immutable set has many advantages.
Kevin Bourrillion
+4  A: 

You can do it in Java 6:

Set<String> h = new HashSet<String>(Arrays.asList("a", "b", "c"));

But why? I don't find it to be more readable than explicitly adding elements.

Jason Nichols
I create it in declaration. It's final property. Thanks
Serg
Ah. It's probably worth noting you can still add elements to a final set. Simply declare the set final, but add elements in the constructor (or anywhere else) as you normally would. A final Collection can still have elements added or removed. Only the reference to the Collection itself if final.
Jason Nichols
+1 to what Jason Nichols said. Don't forget to use Collections.unmodifiableSet(...).
Eli Acherkan
+1  A: 

There is a shorthand that I use that is not very time efficient, but fits on a single line:

Set<String> h = new HashSet<String>(Arrays.asList(new String[] { "a", "b" }));

Again, this is not time efficient since you are constructing an array, converting to a list and using that list to create a set.

When initializing static final sets I usually write it like this:

public static final String[] SET_VALUES = new String[] { "a", "b" };
public static final Set<String> MY_SET = new HashSet<String>(Arrays.asList(SET_VALUES));

Slightly less ugly and efficiency does not matter for the static initialization.

Gennadiy
+2  A: 

A bit convoluted but works from Java 5:

Set<String> h = new HashSet<String>(Arrays.asList(new String[] {  
    "a", "b"
}))

Use a helper method to make it readable:

Set<String> h = asSet ("a", "b");

public Set<String> asSet(String... values) {
    return new HashSet<String>(java.util.Arrays.asList(values));
}
Aaron Digulla
(You didn't need the `new String[] {`)
Kevin Bourrillion
A: 

A generalization of coobird's answer's utility function for creating new HashSets:

public static <T> Set<T> newHashSet(T... objs) {
    Set<T> set = new HashSet<T>();
    for (T o : objs) {
        set.add(o);
    }
    return set;
}
Mark E