Question
How can I create a Java Set containing initial values without calling add() repeatedly?
For example, instead of writing:
Set<String> h = new HashSet<String>();
h.add("a");
h.add("b");
is there a concise one-line approach? This is especially useful when declaring a static final field.
Short Answer
You will learn how to initialize a HashSet from existing values in Java, when to use mutable versus immutable sets, and what final means for a collection reference.
Concept
A HashSet is a Set implementation that stores unique values. Adding the same value more than once does not create duplicates.
To initialize a HashSet with values, first create a collection containing those values, then pass it to the HashSet constructor:
Set<String> letters = new HashSet<>(Arrays.asList("a", "b"));
Arrays.asList("a", "b") creates a list, and new HashSet<>(...) copies its items into a new, mutable HashSet.
This distinction matters:
HashSetis mutable: you can later calladd,remove, orclear.Set.of(...)(Java 9+) is unmodifiable: its contents cannot be changed after creation.finalprevents assigning a variable to a different set; it does not automatically make a mutable set unchangeable.
Mental Model
Think of a Set as a bag with a rule: it can hold each label only once.
Creating an empty HashSet and calling add() is like putting labels into the bag one at a time. Passing Arrays.asList("a", "b") to the constructor is like handing the bag-maker a small list of labels and asking for a bag already filled with them.
final puts a lock on the bag's address, not on the bag's contents. You cannot replace the bag with another bag, but you can still add or remove labels if it is a mutable HashSet.
Syntax and Examples
Use the collection constructor to create a mutable HashSet with initial values:
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
Set<String> letters = new HashSet<>(Arrays.asList("a", "b"));
Because letters is a HashSet, it can be changed later:
letters.add("c");
System.out.println(letters);
The printed order is not guaranteed because HashSet does not preserve insertion order.
For a static final mutable set:
private static final Set<String> ALLOWED_CODES =
new HashSet<>(Arrays.asList("A", "B", "C"));
For Java 9 or later, use Set.of when the set should never be modified:
Step by Step Execution
Consider this code:
Set<String> letters = new HashSet<>(Arrays.asList("a", "b", "a"));
letters.add("c");
System.out.println(letters.size());
System.out.println(letters.contains("a"));
Execution steps:
Arrays.asList("a", "b", "a")creates a list with three positions:a,b, anda.new HashSet<>(...)copies the list values into a set.- The second
"a"is ignored because a set stores unique values. - At this point,
letterscontainsaandb. letters.add("c")adds a new unique value.letters.size()returns3.letters.contains("a")returnstrue.
The exact display order may be , , or another order.
Real World Use Cases
Initializing sets with known values is useful when an application needs quick membership checks.
- Input validation: allowed account types such as
"free","pro", and"enterprise". - HTTP handling: methods that may contain a request body, such as
"POST","PUT", and"PATCH". - Permissions: roles allowed to access an operation.
- File processing: supported file extensions such as
"csv","json", and"xml". - Filtering data: ignoring known test users, blocked identifiers, or reserved words.
For example:
private static final Set<String> SUPPORTED_EXTENSIONS = Set.of("csv", "json", "xml");
boolean isSupported(String extension) {
return SUPPORTED_EXTENSIONS.contains(extension.toLowerCase());
}
A set is a good fit here because the important operation is checking whether a value is present.
Real Codebase Usage
In production code, developers usually expose sets through the Set interface rather than the HashSet implementation:
private static final Set<String> PUBLIC_ROUTES = Set.of("/health", "/login");
This lets the implementation change later without changing code that uses the field.
Prefer immutable constants
For fixed application rules, prefer an unmodifiable set:
private static final Set<String> VALID_STATUSES =
Set.of("NEW", "ACTIVE", "SUSPENDED");
This prevents accidental changes from elsewhere in the class.
Make a mutable copy when needed
A method can start with defaults and then add values based on configuration:
Set<String> enabledFeatures = new HashSet<>(DEFAULT_FEATURES);
if (isBetaUser) {
enabledFeatures.add("beta-dashboard");
}
Use a set in validation guard clauses
Set<String> VALID_SORTS = Set.of(, , );
{
(!VALID_SORTS.contains(sortField)) {
( + sortField);
}
}
Common Mistakes
Expecting final to make a HashSet immutable
This compiles and changes the set:
final Set<String> letters = new HashSet<>(Arrays.asList("a", "b"));
letters.add("c"); // Allowed
final only prevents this reassignment:
letters = new HashSet<>(); // Compile-time error
Use Set.of(...) for an unmodifiable fixed set, or wrap a copy with Collections.unmodifiableSet(...) on older Java versions.
Using Arrays.asList as if it creates a set
Set<String> letters = Arrays.asList("a", "b"); // Does not compile
Arrays.asList returns a List, not a Set. Wrap it in .
Comparisons
| Approach | Java version | Mutable? | Duplicates allowed? | Best use |
|---|---|---|---|---|
new HashSet<>(Arrays.asList("a", "b")) | Java 5+ | Yes | No | A mutable set with initial values |
Set.of("a", "b") | Java 9+ | No | No; duplicates cause an exception | Fixed constants |
new HashSet<>(Set.of("a", "b")) | Java 9+ | Yes | No | Mutable copy of concise initial values |
new LinkedHashSet<>(Arrays.asList("a", "b")) | Java 5+ | Yes | No |
Cheat Sheet
// Mutable HashSet, Java 5+
Set<String> values = new HashSet<>(Arrays.asList("a", "b"));
// Immutable/unmodifiable set, Java 9+
Set<String> values = Set.of("a", "b");
// Mutable HashSet using Java 9+ factory syntax
Set<String> values = new HashSet<>(Set.of("a", "b"));
// Constant fixed set
private static final Set<String> VALUES = Set.of("a", "b");
// Constant reference to a mutable set
private static final Set<String> VALUES =
new HashSet<>(Arrays.asList("a", "b"));
Key rules:
- A
Setremoves duplicate values. HashSetdoes not guarantee iteration order.Set.of(...)rejectsnullvalues and duplicate values.HashSetpermits onenullvalue.
FAQ
How do I initialize a HashSet in one line in Java?
Use:
Set<String> values = new HashSet<>(Arrays.asList("a", "b"));
Import java.util.Arrays, java.util.HashSet, and java.util.Set.
Can I use Set.of instead of new HashSet?
Yes, on Java 9 or later, if the set should not change:
Set<String> values = Set.of("a", "b");
It returns an unmodifiable set, not a HashSet.
Does static final Set make the set immutable?
No. final means the field cannot refer to a different set. If the set is mutable, its elements can still change. Use Set.of for a fixed set.
What happens if initial HashSet values contain duplicates?
Mini Project
Description
Create a small file-extension validator. A fixed set stores the extensions your application supports, and a method checks whether a supplied file name uses one of them. This demonstrates initializing a set with values and using fast membership checks.
Goal
Build a validator that accepts .csv, .json, and .xml file names regardless of letter case.
Requirements
Use a static final Set<String> for supported extensions.
Initialize the set with its values at declaration time.
Extract the extension from a file name.
Treat extension matching as case-insensitive.
Return false for a file name with no extension.
Keep learning
Related questions
Add External JAR Files to an IntelliJ IDEA Java Project
Learn how to add external JAR dependencies to an IntelliJ IDEA Java project using module libraries, and when to use Maven or Gradle instead.
Avoiding Java Code in JSP with JSP 2: EL and JSTL Explained
Learn how to avoid Java scriptlets in JSP 2 using Expression Language and JSTL, with examples, best practices, and common mistakes.
Call a Method After a Delay in Android Java
Learn how to run Java code after a delay in Android using Handler.postDelayed, manage the main thread, and cancel callbacks safely.