ma'am audrey's lessons

ITC 120 › Final › Sets and maps

Sets and maps · Lesson 1 of 2

Sets in Java

This lesson teaches:Abstract data type (ADT)

A collection with one simple promise: no duplicates.

By the end, you can:

  1. explain what a set is (an ADT with unique, unordered values) and tell when a problem needs a set instead of a list;
  2. write A ∪ B, A ∩ B, A − B, B − A, and A △ B for two given sets, draw them on a Venn diagram, and (extra) tell whether one set is a subset of another;
  3. predict what add, contains, remove, and size return on a Java HashSet;
  4. write each set operation in Java with addAll, retainAll, or removeAll on a copy, (extra) check a subset with containsAll, and find the bug when a copy is missing or the wrong set is used;
  5. choose between HashSet, LinkedHashSet, and TreeSet by the order you need.

You need: scratch paper. You may also remember sets from math class; the ideas are the same.

Part 1 · The idea

What a set is

Set

A set is an abstract data type (ADT, explained below) that stores a collection of values with no duplicates and no fixed order. The main question a set answers is: "Is this value in the collection or not?"

We add: Ana, Ben, Ana, CarlaAnaBenAnaCarlaIn a list(like an array)AnaBenAnaCarlaAna is in it twiceIn a set(no duplicates)AnaBenCarlaAnaalready in,so ignored
The same four names go into a list and into a set. The list keeps the second Ana. The set keeps each name once.

What is an abstract data type (ADT)?

Every data structure can be described by answering two questions:

  1. What can I do with it? Its operations, and what each one gives back. For a set: add a value, remove a value, ask "Is this value in it?", and count the values.
  2. How is it stored inside the computer? For a set, it could be an array, a tree, or a hash table. Any of these can work.

An abstract data type (ADT) answers only the first question. "Abstract" means "the idea only, without the details". So the ADT says what you can do, not how it is done. The second question is answered by the code that builds it, called the implementation.

What you can ask vs. how it is builtSari-sari storeDo you haveCoke?Yes, we have!Outside: you can only ask or ask for changescontains?addremoveInside (hidden): each store does it its own wayStore 1: shelves, A to ZA–FG–MN–ZStore 2: bins by letter
A sari-sari store works like an ADT. At the window, you can only ask (contains?) or ask for changes (add, remove). How the stock is arranged inside is hidden, and two stores can do it differently. Both still answer "Do you have Coke?" correctly.

This table matches the store to a set:

In the storeIn a set
You ask: "Do you have Coke?"contains("Coke"): the answer is yes or no (true or false)
New stock arrivesadd("Coke")
The last one is soldremove("Coke")
How the shelves or bins are arranged (you can't see it)how the set is built inside: the implementation

Why split it this way? You can use a set without knowing how it is built, just as you can buy at any sari-sari store without seeing its shelves. And the way it is built can be changed later (to make it faster) without changing the code that uses it.

You already met this idea in the Stacks lesson: what made a stack a stack was the rule "push, pop, peek", not whether it was built with an array or a linked list. Now the idea has a name. A set is described the same way: "add, remove, contains".

Good to know: this course calls stacks and queues data structures and sets and maps abstract data types. Many books call stacks and queues ADTs too, because they can also be described only by what you can do with them. Both views are correct.

The two properties

Every set has these two properties:

  1. Uniqueness. Each value appears at most once (like the second Ana in the ). Adding a value that is already there does nothing.
  2. Unordered. Items have no position (no place in line). In a list or an array, every item has an index: [0] is the first item, [1] is the second, and so on. A set has no index, so it has no "first" item. You can only ask "Is this value in the set?" That is why {1, 2, 3} and {3, 1, 2} are the same set.
1. In a list, order mattersAnaBenCarla≠CarlaAnaBentwo different lists2. In a set, order does not matterAna, Ben, Carla=Carla, Ana, Benthe same set: same names, and that is all that counts3. Asking for "item [0]" (the first item)AnaBenCarla[0][1][2]item [0] is Ana ✓Every item has a place.Ana, Ben, Carlaitem [0]? ✗ no placesInstead, you ask:"Is Ana in it?" Yes ✓
Rows 1 and 2: changing the order makes a different list, but the same set. Row 3: a list can give you item [0] (its first item). A set cannot, because its values have no places, so you ask whether a value is in it instead.

Think of the attendance list

When students tap their ID at the door, some tap twice. But the attendance should list each student once, and it does not matter who came first. That is a set. Compare with the queue at the canteen: there, order matters and the same person can line up again. That is a list or a queue, not a set.

Where you see sets in IT

  • Counting unique visitors to a website (the same person visiting 5 times counts once).
  • Tags on a post, or the list of permissions a user has.
  • Comparing two class lists: who is enrolled in both subjects? (intersection)
ID taps at the door7:58 Ana8:01 Ben8:02 Ana8:05 CarlaAna tapped twiceAttendance✓Ana✓Ben✓Carlaeach name onceSets in ITWebsite visitsABAA4 visits, but2 unique peopleTags on a post#dsa#matieach tag onceTwo class listsWho is in both?A ∩ B
Top: Ana tapped her ID twice, but the attendance lists her once. Bottom: the same idea in IT. Repeat visits count once, a tag appears once per post, and the overlap of two class lists shows who is in both.

Review: subsets (extra)

Extra topic. Subsets go a little beyond this course's required set topics (properties, union, intersection, difference, symmetric difference). Study it if you have time; your teacher will tell you if a quiz or exam uses it.

You may remember subsets from math class. Here is a quick review, because Java can check them too (Part 3).

Subset

A is a subset of B, written A ⊆ B, when every value in A is also in B.

BAAnaBenCarlaDanA ⊆ BEvery valueof A isalso in B.
A = {Ana, Ben} sits inside B = {Ana, Ben, Carla, Dan}, so A ⊆ B. But C = {Ana, Eve} is not a subset of B, because Eve is not in B.

Here are the words and symbols that go with subsets, using the sets in the picture:

TermSymbolMeaningExample
SubsetA ⊆ Bevery value of A is in B{Ana, Ben} ⊆ B
Proper subsetA ⊂ BA ⊆ B, and B has at least one value that A does not{Ana, Ben} ⊂ B (B also has Carla and Dan)
Not a subsetC ⊄ Bat least one value of C is not in B{Ana, Eve} ⊄ B (Eve)
Equal setsA = BA ⊆ B and B ⊆ A: exactly the same values{Ana, Ben} = {Ben, Ana}

Two facts are easy to forget:

  • The empty set { } (the set with nothing in it) is a subset of every set. It has no value that could be missing from B.
  • Every set is a subset of itself (B ⊆ B), but not a proper subset of itself.

Exam trap: one value vs. a set

Ana ∈ B means "the value Ana is in B" (∈ = "is an element of"). {Ana} ⊆ B means "the set holding only Ana is a subset of B". Use ∈ for one value and ⊆ for a set. Writing "Ana ⊆ B" is wrong.

Extra: ⊂ in other books

Extra topic. Open this if a book you read writes ⊂ differently.

Some books write ⊂ for any subset (what we write ⊆). If a question uses ⊂, check how that book or teacher defines it. Rosen (reference 3) uses ⊆ and ⊂ the same way as this lesson.

Part 2 · Combining sets

Set operations

Set operations take two sets and produce a new set. There are four types you need to know. In the examples, A = {1, 2, 3, 4, 5} and B = {4, 5, 6, 7}.

OperationSymbolMeaningExample
UnionA ∪ Bin A or B (or both){1, 2, 3, 4, 5, 6, 7}
IntersectionA ∩ Bin A and B{4, 5}
DifferenceA − Bin A but not in B{1, 2, 3}
DifferenceB − Ain B but not in A{6, 7}
Symmetric differenceA △ Bin A or B, but not both{1, 2, 3, 6, 7}

The lab below draws each operation on a Venn diagram: one circle per set. Values in both sets go in the overlap in the middle; values in only one set go in that circle's outer part. The shaded part is the answer.

Set operations lab

Pick an operation to shade its part of the picture. You can also change A and B (whole numbers, separated by commas).

Exam traps

  1. A − B is not the same as B − A. Order matters for difference: A − B is the part of A outside B, and B − A is the part of B outside A.

    AB1 2 34 56 7≠AB1 2 34 56 7A − B = {1, 2, 3}B − A = {6, 7}
  2. In a union, shared values appear once: {1, 2} ∪ {2, 3} = {1, 2, 3}, not {1, 2, 2, 3}.

    AB123{1, 2} ∪ {2, 3}✓ {1, 2, 3}✗ {1, 2, 2, 3}2 is written only once
  3. When the result has nothing in it, write the empty set: { } (or ∅). Here A and B have the same values, so their circles sit on top of each other and A − B leaves nothing. Try making A and B equal in the lab.

    A, B1 2A = {1, 2}, B = {1, 2}A − B: nothing left= { } or ∅the empty set
  4. A △ B = (A ∪ B) − (A ∩ B) = (A − B) ∪ (B − A). All three give the same answer: the two outer parts, without the middle.

    AB1 2 34 56 7A △ B = {1, 2, 3, 6, 7}= (A ∪ B) − (A ∩ B)all, minus the middle= (A − B) ∪ (B − A)the two outer parts
Extra: other symbols in other books

Extra topic. Open this if a book you read uses other symbols.

Some books write the difference A − B as A \ B, and the symmetric difference A △ B as A ⊕ B (Rosen, reference 3) or A Δ B. They mean the same operations.

Part 3 · In code

Sets in Java

Remember the : what you can ask is one thing, and how the stock is arranged inside is another. Java splits a set into the same two parts:

  • What a set can do: Set is an . It lists the methods every set must have (add, contains, remove, size, and more), but has no code inside. This is the ADT.
  • How it is built: HashSet, LinkedHashSet, and TreeSet are . Each one writes the real code for those methods in its own way. We say each class implements Set.

Here are the three main classes:

ClassBuilt withOrder when you loop through it
HashSeta hash table, through a HashMap inside (next lesson)no guaranteed order
LinkedHashSeta hash table + a linked listthe order you added them
TreeSeta red-black tree, through a TreeMap insidesorted

Wait: said a set has no order. The set ADT promises no order, so you can never ask for "item [2]". LinkedHashSet and TreeSet add an order as an extra, only for looping through the values. They still have no index, and they still keep each value once.

You will see both parts in one line of code: Set<String> present = new HashSet<>(); reads as "present is a Set of Strings, built as a HashSet." The left side (Set) says what you may do with it. The right side (new HashSet<>()) picks how it is built. To get sorted order instead, you would change only the right side, to new TreeSet<>().

HashSet is the usual choice. Its basic methods are add, contains, remove, and size:

import java.util.HashSet;
import java.util.Set;

public class Attendance {
  public static void main(String[] args) {
    Set<String> present = new HashSet<>();

    present.add("Ana");
    present.add("Ben");
    present.add("Carla");
    boolean added = present.add("Ana");   // already there

    System.out.println(added);                   // false
    System.out.println(present.size());          // 3
    System.out.println(present.contains("Ben")); // true
    System.out.println(present.contains("Dan")); // false

    present.remove("Ben");
    System.out.println(present.size());          // 2

    for (String name : present) {    // order not guaranteed
      System.out.println(name);
    }
  }
}

▶ Try it in the Programiz online compiler: tap Copy, paste it there, change public class Attendance to public class Main (Programiz saves your code as Main.java, and Java needs the file name and the public class name to match), then press Run.

Set operations in Java

Java does not have methods named "union" or "intersection". Instead, three methods do the work. Each one changes the set it is called on:

MethodWhat it does to xOperation
x.addAll(y)adds every value of y into xunion
x.retainAll(y)keeps only the values that are also in yintersection
x.removeAll(y)takes out every value that is in ydifference
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

public class SetOperations {
  public static void main(String[] args) {
    Set<Integer> a = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5));
    Set<Integer> b = new HashSet<>(Arrays.asList(4, 5, 6, 7));

    Set<Integer> union = new HashSet<>(a);   // copy of A
    union.addAll(b);                         // add all of B
    System.out.println("A u B = " + union);  // [1, 2, 3, 4, 5, 6, 7]

    Set<Integer> inter = new HashSet<>(a);
    inter.retainAll(b);                      // keep only what B has
    System.out.println("A n B = " + inter);  // [4, 5]

    Set<Integer> aMinusB = new HashSet<>(a);
    aMinusB.removeAll(b);                    // take out B's values
    System.out.println("A - B = " + aMinusB); // [1, 2, 3]

    Set<Integer> bMinusA = new HashSet<>(b);
    bMinusA.removeAll(a);
    System.out.println("B - A = " + bMinusA); // [6, 7]

    Set<Integer> sym = new HashSet<>(union); // A u B ...
    sym.removeAll(inter);                    // ... minus A n B
    System.out.println("A sym B = " + sym);  // [1, 2, 3, 6, 7]

    System.out.println("A is still " + a);   // [1, 2, 3, 4, 5]
  }
}

▶ Try it in the Programiz online compiler: tap Copy, paste it there, change public class SetOperations to public class Main (Programiz saves your code as Main.java, and Java needs the file name and the public class name to match), then press Run.

The code prints u, n, and sym instead of ∪, ∩, and △, because some consoles cannot show those symbols. Small whole numbers like these usually come out in increasing order from a HashSet, but that is not guaranteed (the names in the attendance example did not). The values are what matter, not their order.

The #1 bug: forgetting to copy

Because addAll, retainAll, and removeAll change the set itself, always start from a copy: new HashSet<>(a). If you write a.addAll(b) directly, A is now the union, and every later operation that uses A gives the wrong answer.

Spot the bug

This code should print A − B and B − A. The B − A part was copied from the A − B part, and two lines were not fully updated. Which lines, and what does the code print?

 1Set<Integer> a = new HashSet<>(Arrays.asList(10, 20, 30));
 2Set<Integer> b = new HashSet<>(Arrays.asList(20, 40));
 3
 4Set<Integer> aMinusB = new HashSet<>(a);
 5aMinusB.removeAll(b);
 6System.out.println("A - B: " + aMinusB);
 7
 8Set<Integer> bMinusA = new HashSet<>(b);
 9aMinusB.removeAll(a);
10System.out.println("B - A: " + aMinusB);
Show the answer

Lines 9 and 10 still use aMinusB. Line 9 should be bMinusA.removeAll(a);, and line 10 should print bMinusA.

As written, it prints A - B: [10, 30], then removes A's values from aMinusB (which empties it) and prints B - A: []. The correct B − A is {40}.

This kind of copy-paste mistake is common. When you copy a block of code, check every variable name in it.

Subsets in Java (extra)

Extra topic, like the subsets review in Part 1.

Java has no method named "subset". You check with containsAll. This table shows each subset question in Java:

By handIn JavaRead it as
A ⊆ Bb.containsAll(a)"Does b contain all of a?"
A ⊂ Bb.containsAll(a) && !a.equals(b)"all of a, and not the same set"
A = Ba.equals(b)"exactly the same values?"
x ∈ Bb.contains(x)"is this one value in b?"

Watch the direction: A ⊆ B is written b.containsAll(a), so the bigger set goes first. And unlike addAll, retainAll, and removeAll, containsAll changes nothing. It only answers true or false, so no copy is needed.

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;

public class Subsets {
  public static void main(String[] args) {
    Set<String> b = new HashSet<>(Arrays.asList("Ana", "Ben", "Carla", "Dan"));
    Set<String> a = new HashSet<>(Arrays.asList("Ana", "Ben"));
    Set<String> c = new HashSet<>(Arrays.asList("Ana", "Eve"));
    Set<String> empty = new HashSet<>();

    System.out.println(b.containsAll(a));     // true:  A is a subset of B
    System.out.println(b.containsAll(c));     // false: Eve is not in B
    System.out.println(b.containsAll(empty)); // true:  { } is a subset of every set
    System.out.println(a.containsAll(a));     // true:  every set is a subset of itself

    boolean proper = b.containsAll(a) && !a.equals(b);
    System.out.println(proper);               // true:  A is a proper subset of B

    Set<String> d = new TreeSet<>(Arrays.asList("Dan", "Carla", "Ben", "Ana"));
    System.out.println(b.equals(d));          // true:  same values (order and class don't matter)

    System.out.println(b.contains("Ana"));    // true:  one value, so contains
    System.out.println(a.size() + " " + b.size()); // 2 4: containsAll changed nothing
  }
}

▶ Try it in the Programiz online compiler: tap Copy, paste it there, change public class Subsets to public class Main (Programiz saves your code as Main.java, and Java needs the file name and the public class name to match), then press Run.

equals ignores order, and even the class: a HashSet and a TreeSet with the same values are equal.

Part 4 · Your turn

Practice

For each pair, write A ∪ B, A ∩ B, A − B, B − A, and A △ B. Drawing a quick Venn diagram first makes it easy: put shared values in the middle. After the four problems, a short coding task turns one of these operations into Java.

Problem 1

A = { 2, 4, 6, 8, 10 }
B = { 3, 6, 9, 12 }

Show the answer
A ∪ B{ 2, 3, 4, 6, 8, 9, 10, 12 }
A ∩ B{ 6 }
A − B{ 2, 4, 8, 10 }
B − A{ 3, 9, 12 }
A △ B{ 2, 3, 4, 8, 9, 10, 12 }

Problem 2

A = { 15, 25, 35, 45 }
B = { 45, 35, 25, 15 }

Show the answer
A ∪ B{ 15, 25, 35, 45 }
A ∩ B{ 15, 25, 35, 45 }
A − B{ }
B − A{ }
A △ B{ }

A and B have the same values (the order does not matter in a set), so they are equal sets. Nothing is left over in either difference, and nothing is in one but not both.

Problem 3

A = { 1, 2, 3 }
B = { }

Show the answer
A ∪ B{ 1, 2, 3 }
A ∩ B{ }
A − B{ 1, 2, 3 }
B − A{ }
A △ B{ 1, 2, 3 }

B is the empty set. Union with an empty set changes nothing, and intersection with it is always empty.

Problem 4: the library tap-in log

Students tap their ID cards when they enter the library, and they tap again each time they come back from a break. Monday morning's log, in tap order:

1021, 1045, 1021, 1102, 1045, 1021, 1230

Tuesday's different visitors were {1045, 1230, 1301}.

  1. How many different students visited on Monday?
  2. Which students came on both days?
  3. Which students came on Monday but not on Tuesday?
Show the answer
  1. Write the log as a set, keeping each ID once: Monday = {1021, 1045, 1102, 1230}. That is 4 different students, even though there were 7 taps.
  2. Both days = Monday ∩ Tuesday = {1045, 1230}.
  3. Monday only = Monday − Tuesday = {1021, 1102}.

In Java, the set removes the repeated taps for you. Adding the whole log to a HashSet keeps each ID once:

 1import java.util.Arrays;
 2import java.util.HashSet;
 3import java.util.Set;
 4
 5public class Library {
 6  public static void main(String[] args) {
 7    Set<Integer> monday = new HashSet<>(Arrays.asList(1021, 1045, 1021, 1102, 1045, 1021, 1230));
 8    Set<Integer> tuesday = new HashSet<>(Arrays.asList(1045, 1230, 1301));
 9    System.out.println(monday.size());   // 4: each ID is kept once
10
11    Set<Integer> both = new HashSet<>(monday);
12    both.retainAll(tuesday);             // came both days
13    System.out.println(both);            // [1045, 1230]
14
15    Set<Integer> mondayOnly = new HashSet<>(monday);
16    mondayOnly.removeAll(tuesday);       // Monday but not Tuesday
17    System.out.println(mondayOnly);      // [1021, 1102]
18  }
19}

▶ Try it in the Programiz online compiler: tap Copy, paste it there, change public class Library to public class Main (Programiz saves your code as Main.java, and Java needs the file name and the public class name to match), then press Run.

Your coding task: A △ B without changing A or B

In , A △ B was the two outer parts of the Venn diagram: (A − B) ∪ (B − A). Now write it in Java.

Finish symDiff in about 5 lines where it says YOUR CODE. Use removeAll and addAll from Part 3, and watch out for the #1 bug: work on copies, so a and b stay the same. The tests use the pairs from Problems 1 to 3 above, so you can compare with your paper answers. Run it: each printed line must match its expected comment.

 1import java.util.Arrays;
 2import java.util.HashSet;
 3import java.util.Set;
 4
 5public class Main {
 6  // Returns A sym B = (A - B) u (B - A).
 7  // It must NOT change a or b.
 8  static Set<Integer> symDiff(Set<Integer> a, Set<Integer> b) {
 9    // YOUR CODE:
10    // 1. Copy a, then remove all of b from the copy (A - B).
11    // 2. Copy b, then remove all of a from the copy (B - A).
12    // 3. Add all of B - A into A - B, and return it.
13
14    return new HashSet<>();
15  }
16
17  public static void main(String[] args) {
18    // Problem 1 from the paper practice
19    Set<Integer> a = new HashSet<>(Arrays.asList(2, 4, 6, 8, 10));
20    Set<Integer> b = new HashSet<>(Arrays.asList(3, 6, 9, 12));
21    System.out.println(symDiff(a, b)); // expected: [2, 3, 4, 8, 9, 10, 12]
22    System.out.println(symDiff(b, a)); // expected: [2, 3, 4, 8, 9, 10, 12]
23    System.out.println(a);             // expected: [2, 4, 6, 8, 10] (unchanged)
24    System.out.println(b);             // expected: [3, 6, 9, 12] (unchanged)
25
26    // Problem 2: same values, so nothing is left
27    Set<Integer> c = new HashSet<>(Arrays.asList(15, 25, 35, 45));
28    Set<Integer> d = new HashSet<>(Arrays.asList(45, 35, 25, 15));
29    System.out.println(symDiff(c, d)); // expected: []
30
31    // Problem 3: B is the empty set
32    Set<Integer> e = new HashSet<>(Arrays.asList(1, 2, 3));
33    Set<Integer> empty = new HashSet<>();
34    System.out.println(symDiff(e, empty)); // expected: [1, 2, 3]
35  }
36}

▶ This program runs as is. Try it in the Programiz online compiler: tap Copy, paste it there, and press Run.

Show one possible answer
 1static Set<Integer> symDiff(Set<Integer> a, Set<Integer> b) {
 2  Set<Integer> aMinusB = new HashSet<>(a);   // copy of A
 3  aMinusB.removeAll(b);                      // A - B
 4  Set<Integer> bMinusA = new HashSet<>(b);   // copy of B
 5  bMinusA.removeAll(a);                      // B - A
 6  aMinusB.addAll(bMinusA);                   // (A - B) u (B - A)
 7  return aMinusB;
 8}

Output, one per line: [2, 3, 4, 8, 9, 10, 12] twice (A △ B and B △ A are the same set), then [2, 4, 6, 8, 10] and [3, 6, 9, 12] (A and B did not change), then [] and [1, 2, 3].

Another correct answer follows the Part 3 code: copy A and add all of B (the union), copy A and keep only B's values (the intersection), then remove the intersection from the union.

Here is the most common mistake: skipping the copies.

 1a.removeAll(b);   // no copy: changes a itself
 2b.removeAll(a);
 3a.addAll(b);
 4return a;

The first line takes B's values out of A itself, so A is now [2, 4, 8, 10]. The second line removes that changed A from B, which takes out nothing. The last line adds B back, so the method returns [2, 3, 4, 6, 8, 9, 10, 12]: 6 is back, even though it is in both sets. And since a itself was changed, the next tests are wrong too. Every line of the first test prints that same wrong set, and Problem 2 prints all four values instead of [].

Part 5 · Check yourself

Self-check

Not graded. Tap an answer to see if you got it, and read why.

  1. Which two properties describe a set?

  2. You call add(5) on a set that already contains 5. What happens?

  3. A = {1, 2, 3}, B = {3, 4}. What is A ∩ B?

  4. A = {1, 2, 3}, B = {3, 4}. What is A △ B (symmetric difference)?

  5. If A and B are equal sets, what is A − B?

  6. Which Java method keeps only the elements that are also in another set?

  7. Why do we write new HashSet<>(a) before calling union.addAll(b)?

  8. Which Java set keeps its elements in sorted order?

  9. (Extra) A = {1, 2} and B = {1, 2, 3}. Which is true?

  10. (Extra) Which Java line checks whether A ⊆ B?

Score: 0 / 10

Key takeaways

  1. A set stores unique values with no order. Duplicates are ignored.
  2. Union = or. Intersection = and. A − B = in A but not in B (so A − B and B − A differ). Symmetric difference = in one but not both.
  3. In Java: addAll (union), retainAll (intersection), removeAll (difference).
  4. Those methods change the set itself, so copy first with new HashSet<>(a).
  5. HashSet: no order. LinkedHashSet: insertion order. TreeSet: sorted.
  6. (Extra) A ⊆ B when every value of A is in B. In Java: b.containsAll(a) (bigger set first).

Next lesson: Maps and hashing, where you will see how a HashSet and HashMap find things so fast.

References

  1. Oracle, "Set (Java SE 21 & JDK 21)," "HashSet," and "TreeSet," Java API documentation. docs.oracle.com
  2. Oracle, "The Set Interface," The Java Tutorials. docs.oracle.com/javase/tutorial
  3. K. H. Rosen, Discrete Mathematics and Its Applications, 8th ed. McGraw-Hill, 2019, Section 2.2 (Set operations).