import java.util.*;

class Example {
    public static void main(String[] args) {
        Set<String> identityA = newIdentityHashSet();
        Set<String> identityB = newIdentityHashSet();
        
        identityA.add("X");
        identityB.add(new String("X"));
        
        System.out.println("This should be [X, X]:");
        System.out.println("    " + unionInHashSet(identityA, identityB));
        
        System.out.println("Returning an identity hash set solves this:");
        System.out.println("    " + unionInIdentityHashSet(identityA, identityB));
        
        Set<String> a = new HashSet<>(identityA);
        Set<String> b = new HashSet<>(identityB);
        
        System.out.println("But now the union of regular sets is messed up:");
        System.out.println("    " + unionInIdentityHashSet(a, b));
    }
    
    static <T> Set<T> unionInHashSet(Set<T> a, Set<T> b) {
        Set<T> union = new HashSet<>();
        union.addAll(a);
        union.addAll(b);
        return union;
    }
    
    static <T> Set<T> unionInIdentityHashSet(Set<T> a, Set<T> b) {
        Set<T> union = newIdentityHashSet();
        union.addAll(a);
        union.addAll(b);
        return union;
    }
    
    static <T> Set<T> newIdentityHashSet() {
        return Collections.newSetFromMap(new IdentityHashMap<>());
    }
}