What a set is
An ArrayList keeps every value you put in it, repeats included. Sometimes you only care about which values there are, not how many times each one came. A set is made for that: it holds each value once, and adding a value that is already inside changes nothing.
Java's everyday set is HashSet. The main operations are:
new HashSet<>()makes an empty set. A set of strings has the typeHashSet<String>.s.add(x)putsxin the sets.s.contains(x)istruewhenxis in the set.s.size()gives how many values the set holds.new HashSet<>(list)builds a set from a list. Repeats in the list go in once.
HashSet<String> pets = new HashSet<>(List.of("cat", "dog", "cat"));
pets.add("fish");
pets.add("dog");
System.out.println(pets.size());
System.out.println(pets.contains("dog"));
The list has "cat" twice, but the set holds it once. Adding "fish" makes the set bigger. Adding "dog" does nothing, because it is already there. The output is:
3
true
Both add and remove also return a boolean: add gives true when the value was new and false when it was already in the set. You can ignore that result, as the lesson does.
Why use a set
Checking s.contains(x) is fast, even for a big set. A list's contains looks at the values one by one until it finds a match. When a program asks "have I seen this value?" many times, a set is the right tool.
Building a set from a list is the quickest way to ask "which different values are in here?". The set above, made from five names, holds three. If you then need the values as a list again, you can pass the set to new ArrayList<>(set), but remember that the order is not promised.
Things to remember in Java
- A set holds objects, like a
HashMapdoes. A set of numbers is aHashSet<Integer>, neverHashSet<int>. Java converts betweenintandIntegerfor you when you add or check a number. - A set has no order and no indexes. There is no
get(i), and a printed set may show its values in any order. - Two strings count as the same value when they are equal in content, so
"Ava"typed twice goes in once.
The lesson's task
The camp's sign-up list names has Ava and Leo twice. The task has three parts: build a set kids from the list, add Zoe and then Ava, and print Leo is coming if kids contains "Leo". The code around it already prints the size twice.
HashSet<String> kids = new HashSet<>(names);
System.out.println(kids.size() + " kids");
kids.add("Zoe");
kids.add("Ava");
System.out.println(kids.size() + " kids");
if (kids.contains("Leo")) {
System.out.println("Leo is coming");
}
The list holds five names, but only three different ones: Ava, Leo and Mia. So the first line is 3 kids. Zoe is new, so the size grows to 4. Ava is already in the set, so adding her changes nothing. The output is:
3 kids
4 kids
Leo is coming
Common mistakes
- Writing
kids.get(0). A set has no indexes, so the method doesn't exist. - Expecting
addto make the set bigger every time. Only a new value does. - Declaring the set with a primitive type, like
HashSet<int>. It doesn't compile; useHashSet<Integer>.
Key takeaways
- A
HashSetholds each value once. add,containsandsizecover most uses.new HashSet<>(list)removes the repeats of a list.- Don't rely on the order of a set's values.
