32

How can I create a Set in java, and then add objects to it when it is constructed. I want to do something like:

testCollision(getObject(), new HashSet<MazeState>(){add(thing);});

But that doesn't seem quite right.

robert_x44
  • 9,224
  • 1
  • 32
  • 37
Dartoxian
  • 750
  • 1
  • 6
  • 10

7 Answers7

71

Since Java 7, to instantiate a single-element, immutable Set, you can use:

Collections.singleton(thing);

Returns an immutable set containing only the specified object. The returned set is serializable.

Javadoc reference: Collections.singleton(T)


In Java 8 you can instantiate a Set containing any number of your objects with the following, which is an adaptation of this answer:

Stream.of(thing, thingToo).collect(Collectors.toSet());
Community
  • 1
  • 1
fspinnenhirn
  • 1,784
  • 1
  • 13
  • 27
28

In Java 5

new HashSet<MazeState>(Arrays.asList(thing));

Arrays.asList(thing) converts your thing to the list of one element, and from that list set is created.

For the reference:
http://download.oracle.com/javase/6/docs/api/java/util/Arrays.html#asList(T...)

Nikita Rybak
  • 67,365
  • 22
  • 157
  • 181
24

Since Java 9 you can also do it like this:

 Set<String> immutableSet = Set.of("value1", "value2");
 Set<Integer> immutableInt = Set.of(1, 2);

 List<String> immutableList = List.of("item1", "item2");

 Map<String, String> immutableMap = Map.of("key1", "value1", "key2", "value2", "key3", "value3");

Observe that any Sets/Maps/Lists created this way will be immutable (if my naming convention didn't convince you ;)

Utku
  • 2,025
  • 22
  • 42
Cliffsb
  • 241
  • 2
  • 2
17

You can use double-braces:

testCollision(getObject(), new HashSet<MazeState>(){{ add(obj1); add(obj2);}};

or:

Set<String> set = new HashSet<String>(){{
  add("hello");
  add("goodbye");
}};

This is called double-brace initialization, and it's one of the lesser known features of Java. What it does is cause the compiler to create an anonymous inner class that does the creation and manipulation for you (So, for example, if your class was final, you couldn't use it.)

Now, having said that - I'd encourage you only to use it in cases where you really need the brevity. It's almost always better to be more explicit, so that it's easier to understand your code.

Kylar
  • 8,876
  • 8
  • 41
  • 75
  • 4
    'double-brace initialization' is not exactly a 'feature': it wasn't introduced on purpose. It's just a clever use of initialization block and anonymous classes. Maybe too clever :) – Nikita Rybak Jan 04 '11 at 17:15
  • 2
    Double brace initialization also causes, iiuc, a subclass of the class to be created. This can eat memory and, if you're mistakenly relying on actual classes elsewhere, cause unexpected failures. That being said, I use double brace initialization a lot in my test code since it's very clear what's going on that way and I don't need to worry about memory and the like. – RHSeeger Jan 04 '11 at 17:48
  • 1
    IntelliJ's warnings supplement the warnings already mentioned above **Double brace initialization can cause memory leaks when used from a non-static context, because the anonymous class created will maintain a reference to the surrounding object. It has worse performance than regular initialization because of the additional class loading required. It can cause equals() comparisons to fail, if the equals() method does not accept subclasses as parameter (see link above). And finally, pre Java 9 it cannot be combined with the diamond operator, because that cannot be used with anonymous classes.** – Mark Jeronimus Sep 25 '18 at 07:49
8

If you don't mind immutability then you may use Google Guava's ImmutableSet class:

ImmutableSet.of(new MazeState(), new MazeState());
Nick is tired
  • 6,860
  • 20
  • 39
  • 51
Serge Mask
  • 1,331
  • 1
  • 9
  • 6
  • Just for reference, this method is from the Google Guava library rather than the standard JDK. Guava has a load of really nice features that are well worth checking out, but if all you want is this one method then just be aware that you are importing a huge library. – Stormcloud Jun 16 '15 at 15:53
5

You can use the util method from com.google.common.collect, that is a pretty nice one: Sets.newHashSet("your value1", "your valuse2");

Radu Linu
  • 1,143
  • 13
  • 29
1

Other answers are correct but want to add one more way .using initializer block

new HashSet<MazeState>() {

            {
                add(new MazeState());
                add(new MazeState());
            }
        };
jmj
  • 237,923
  • 42
  • 401
  • 438