Set Basics

 
/**
 * SET BASICS - COLLECTIONS
 * ------------------------
 * Set is a Collection of UNIQUE elements
 * 
 * Key characteristics:
 *  - No duplicates allowed
 *  - No index (no get(0))
 *  - Fast lookups (especially HashSet)
 * 
 * Implementations:
 *  - HashSet (more uses), fastest, no order quaranted
 */

package com.minte9.collections.sets;

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

public class SetBasics {            
    public static void main(String[] args) {     

        // Create a set
        Set<String> fruits = new HashSet<>();

        // Add elements
        fruits.add("Apple");
        fruits.add("Banana");
        fruits.add("Apple"); // ignored
        fruits.add("Orange");
        System.out.println(fruits);  // [Apple, Banana, Orange] (no duplicate)

        // Check existance
        boolean exists = fruits.contains("Apple");  // O(1) fast
        System.out.println(exists);  // true

        // Remove elements
        fruits.remove("Orange");
        System.out.println("After removal: " + fruits);  // [Apple, Banana]

        // Iterate through elements
        for (String f : fruits) {
            System.out.println(f);
                // Apple
                // Banana
        }
    }
}

Set Example

 
/**
 * HASHSET Implementation
 * ----------------------
 * Concept:
 *  - No duplicates allowed
 *  - Unordered (HashSet)
 *  - Fast lookups
 * 
 * HashSet (more used) uses hasing internally.
 * 
 * To check for duplicates HashSet uses two methods inherited from Object:
 *  - hashCode() for quick access (performance)
 *  - equals() for actual equality check
 * 
 * The default implementation from Object:
 *  - equals() checks if two references are the SAME OBJECT in memory
 *  - hashCode() generates a number based on memory location
 * 
 * This means:
 *      new Song("Imagine", "John Lennon")
 *      new Song("Imagine", "John Lennon")
 * are considered DIFFERENT unless we oberride Object's methods.
 * 
 * Overriding equals() and hashCode() is optional.
 * Java allows you to rely on the default behavior.
 */

package com.minte9.collections.sets;

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

public class HashSetExample {
    public static void main(String[] args) {

        // Custom type
        Set<Song> songs = new HashSet<>();
        songs.add(new Song("Imagine", "John Lennon"));
        songs.add(new Song("Imagine", "John Lennon")); // duplicate
        songs.add(new Song("Africa", "Toto"));
        songs.add(new Song("Africa", "Weezer"));  // not a duplicate

        System.out.println(songs); 
            // Imagine (John Lennon), Africa (Weezer), Africa (Toto)
    }
}

class Song {
    private String title;
    private String artist;

    public Song (String title, String artist) {
        this.title = title;
        this.artist = artist;
    }

    @Override
    public String toString() {
        return title + " (" + artist + ")";
    }

    @Override
    public boolean equals(Object o) {
        Song other = (Song) o;
        return title.equals(other.title) && artist.equals(other.artist);
    }

    @Override
    public int hashCode() {
        return Objects.hash(title, artist);
    }
}

TreeSets

 
/**
 * TreeSet stores UNIQUE elements and automatically keeps them sorted.
 * 
 * Operations like add(), remove(), contains() run in O(log n),
 * which is slightly slower than HashSet (O(1) average)
 * but still very efficient.
 */

package com.minte9.collections.sets;

import java.util.TreeSet;
import java.util.Set;

public class TreeSets {
    public static void main(String[] args) {

        Set<A> myTree = new TreeSet<>();
        myTree.add(new A("F", "1"));
        myTree.add(new A("G", "2"));
        myTree.add(new A("H", "4"));
        myTree.add(new A("H", "3"));

        System.out.println(myTree); // [F:1, G:2, H:4]
    }
}

class A implements Comparable<A> {

    public String title;
    public String artist;

    public A(String t, String a) {
        title = t;
        artist = a;
    }

    @Override
    public int compareTo(A a) {
        return title.compareTo(a.title);
    }

    @Override
    public String toString() {
        return title + ":" + artist;
    }
}






Questions and answers:
Clink on Option to Answer




1. What is the main rule of a HashSet?

  • a) It stores duplicate values
  • b) It stores unique values only

2. Does a HashSet guarantee order?

  • a) Yes, insertion order is preserved
  • b) No, order is not guaranteed

3. Which two methods are used to detect duplicates in a HashSet?

  • a) equals() and hashCode()
  • b) compareTo() and toString()

4. Why were two identical Song objects initially considered different?

  • a) Because equals() and hashCode() were not overridden
  • b) Because the HashSet was full

5. What does a TreeSet do differently than a HashSet?

  • a) It allows duplicates
  • b) It keeps elements sorted

6. Which data structure is generally faster for simple operations?

  • a) HashSet
  • b) TreeSet


References: