Arrays have a fixed size, but in practice, Add/delete free collection is more often used. The three most used ones are List, Set, and Map.
Learning Objectives
- Know the difference between
ArrayListandLinkedList - Know the difference in operation between
HashSet(unordered) andTreeSet(sorted) - Create key → value mapping with
HashMap - Traverse the collection as
for-each - Knows immutable collection factories such as
List.of(...),Set.of(...),Map.of(...)
Key concepts
1) List<E>
import java.util.ArrayList;
import java.util.List;
List<String> langs = new ArrayList<>();
langs.add("Java");
langs.add("Spring");
langs.remove(0);
System.out.println(langs.size()); // 1
System.out.println(langs.get(0)); // Spring
ArrayList: Index access is fast and adding to the end is fast. Common default choicesLinkedList: Add/delete fast on both ends. Occasionally used for cueing purposes
2) Set<E>
import java.util.HashSet;
import java.util.Set;
Set<String> tags = new HashSet<>();
tags.add("java");
tags.add("java"); //Ignore duplicates
System.out.println(tags.size()); // 1
HashSet: Fast Add/Search, in no particular orderTreeSet: automatic sorting, slightly slower
3) Map<K, V>
import java.util.HashMap;
import java.util.Map;
Map<String, Integer> score = new HashMap<>();
score.put("Korean language", 90);
score.put("math", 85);
System.out.println(score.get("Korean language")); // 90
System.out.println(score.containsKey("english")); // false
4) Immutable Factory
List<String> l = List.of("A", "B", "C");
Set<Integer> s = Set.of(1, 2, 3);
Map<String, Integer> m = Map.of("a", 1, "b", 2);
// l.add("D"); // UnsupportedOperationException
This is a pattern that cannot be modified, is light, and is frequently used.
See as example
Example 1 — Using ArrayListBasics.java : ArrayList
import java.util.ArrayList;
import java.util.List;
public class ArrayListBasics {
public static void main(String[] args) {
List<String> langs = new ArrayList<>();
langs.add("Java");
langs.add("Spring");
langs.add("Kotlin");
langs.remove("Kotlin");
for (String s : langs) System.out.println(s);
System.out.println("size=" + langs.size());
}
}
Execution result
Java
Spring
size=2
Memo: remove(Object) and remove(int index) are distinguished by their signatures.
Example 2 — SetBasics.java : HashSet vs TreeSet
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;
public class SetBasics {
public static void main(String[] args) {
Set<Integer> h = new HashSet<>();
Set<Integer> t = new TreeSet<>();
for (int v : new int[]{3, 1, 4, 1, 5, 9, 2, 6}) {
h.add(v);
t.add(v);
}
System.out.println("HashSet : " + h);
System.out.println("TreeSet : " + t); //sort
}
}
Execution result (HashSet order may vary)
HashSet : [1, 2, 3, 4, 5, 6, 9]
TreeSet : [1, 2, 3, 4, 5, 6, 9]
Note: The output order of HashSet is not guaranteed. If the order is important, use LinkedHashSet/TreeSet.
Example 3 — MapBasics.java : HashMap
import java.util.HashMap;
import java.util.Map;
public class MapBasics {
public static void main(String[] args) {
Map<String, Integer> score = new HashMap<>();
score.put("Korean language", 90);
score.put("math", 85);
score.put("english", 78);
for (Map.Entry<String, Integer> e : score.entrySet()) {
System.out.println(e.getKey() + " -> " + e.getValue());
}
System.out.println("Korean=" + score.get("Korean language"));
System.out.println("French=" + score.getOrDefault("French", -1));
}
}
Execution results (order may vary)
Korean -> 90
Math -> 85
English -> 78
Korean=90
French=-1
Note: getOrDefault handles default values for missing keys in one line.
Example 4 — ImmutableCollections.java: Immutable Factory
import java.util.List;
import java.util.Map;
import java.util.Set;
public class ImmutableCollections {
public static void main(String[] args) {
List<String> l = List.of("A", "B", "C");
Set<Integer> s = Set.of(1, 2, 3);
Map<String, Integer> m = Map.of("a", 1, "b", 2);
System.out.println(l);
System.out.println(s);
System.out.println(m);
try {
l.add("D");
} catch (UnsupportedOperationException e) {
System.out.println("immutable: unmodifiable");
}
}
}
Execution result (Set/Map order may vary)
[A, B, C]
[3, 2, 1]
{b=2, a=1}
immutable: unmodifiable
Note: These factories are neat for small constant collections that are frequently used in code.
Common Mistakes
- Assume the
HashSetorder is constant - Put the key
nullinHashMapand then forget aboutNullPointerException - Directly call
removewhile traversing the collection →ConcurrentModificationException Arrays.asList(new int[]{1,2,3})isList<int[]>, notList<Integer>- Try to modify
List.of(...)results
Cleanup
- Most common choices:
ArrayList,HashSet,HashMap - If alignment is required,
TreeSet/TreeMap - Small constant collection:
List.of/Map.of - Modifications made while touring the collection must be done in a safe manner such as
iterator.remove.
Try it yourself
cd 03_Collection_Generic/12_List_Set_Map/src
javac MapBasics.java
java MapBasics