25

In Java, how do I create a final Set that's populated at construction? I want to do something like the following:

static final Set<Integer> NECESSARY_PERMISSIONS 
    = new HashSet<Integer>([1,2,3,6]);

but I don't know the proper syntax in Java.

cнŝdk
  • 31,391
  • 7
  • 56
  • 78
Sal
  • 3,179
  • 7
  • 31
  • 41
  • 3
    I nominate this for reopening because there is the subtle difference: this asks specifically for final whereas the other for the general paradigm. For example, an answer that includes `Collections.unmodifiableSet()` would be proper for this but not the other. – demongolem Dec 14 '16 at 17:22

6 Answers6

65

Try this idiom:

import java.util.Arrays;

new HashSet<Integer>(Arrays.asList(1, 2, 3, 6))
Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
23

You might consider using Guava's ImmutableSet:

static final Set<Integer> NECESSARY_PERMISSIONS = ImmutableSet.<Integer>builder()
        .add(1)
        .add(2)
        .add(3)
        .add(6)
        .build();
static final Set<String> FOO = ImmutableSet.of("foo", "bar", "baz");

Among other things, this is significantly faster (and ~3 times more space-efficient) than HashSet.

Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
Paul Bellora
  • 54,340
  • 18
  • 130
  • 181
10

Using Google Guava library you can use ImmutableSet, which is designed exactly to this case (constant values):

static final ImmutableSet<Integer> NECESSARY_PERMISSIONS =
        ImmutableSet.of(1,2,3,6);

Old-school way (without any library):

static final Set<Integer> NECESSARY_PERMISSIONS =
        new HashSet<Integer>(Arrays.asList(1,2,3,6));

EDIT:

In Java 9+ you can use Immutable Set Static Factory Methods:

static final Set<Integer> NECESSARY_PERMISSIONS =
        Set.of(1,2,3,6);
Grzegorz Rożniecki
  • 27,415
  • 11
  • 90
  • 112
8

The easiest way, using standard Java classes, is

static final Set<Integer> NECESSARY_PERMISSIONS = 
    Collections.unmodifiableSet(new HashSet<Integer>(Arrays.asList(1, 2, 3, 6)));

But you can also use a static initializer, or delegate to a private static method:

static final Set<Integer> NECESSARY_PERMISSIONS = createNecessaryPermissions();

Note the unmodifiableSet wrapper, which guarantees that your constant set is indeed constant.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
8

You can do this in the following way which IMO is much better and more concise than other examples in this topic:

public static <T> Set<T> set(T... ts) {
    return new HashSet<>(Arrays.asList(ts));
}

after importing it statically you can write something like this:

public static final Set<Integer> INTS = set(1, 2, 3);
Jonathan Fuerth
  • 2,080
  • 2
  • 18
  • 21
Konstantin Solomatov
  • 10,252
  • 8
  • 58
  • 88
3
Set<String> s = new HashSet<String>() {{  
  add("1"); add("2"); add("5");  
}};
Andrew Logvinov
  • 21,181
  • 6
  • 52
  • 54
  • 6
    Be aware of [double brace initialization drawbacks](http://stackoverflow.com/questions/924285/efficiency-of-java-double-brace-initialization). – Grzegorz Rożniecki Feb 27 '12 at 21:33