interface Comparable { boolean equals(Object x); boolean less(Object x); } interface Set { boolean contains(A x); Set include(A x); } abstract class Tree implements Set { public abstract boolean contains(A x); public abstract Tree insert (A x); public Set include(A x) { return insert(x); } } class EmptyTree extends Tree { public boolean contains(A x) { return false; } public Tree insert(A x) { return new Branch(x, this, this); } } class Branch extends Tree { A elem; Tree left; Tree right; public Branch(A elem, Tree left, Tree right) { this.elem = elem; this.left = left; this.right = right; } public boolean contains(A x) { if (x.less(elem)) return left.contains(x); else if (elem.less(x)) return right.contains(x); else // we assume total ordering, therefore x.equals(elem) return true; } public Tree insert(A x) { if (x.less(elem)) return new Branch(elem, left.insert(x), right); else if (elem.less(x)) return new Branch(elem, left, right.insert(x)); else // we assume total ordering, therefore x.equals(elem) return this; } } class ComparableString implements Comparable { private String s; ComparableString(String s) { this.s = s; } public boolean less(Object other) { if (other instanceof ComparableString) return s.compareTo(((ComparableString)other).s) < 0; else throw new Error("can't compare to non-strings"); } } public class TestForDuplicates { public static void main(String[] args) { Set set = new EmptyTree(); for (int i = 1; i < args.length; i++) set.include(new ComparableString(args[i])); System.out.println( set.contains(new ComparableString(args[0]))); } }