interface Comparable { boolean less(A x); } interface Set> { boolean contains(A x); Set include(A x); } class ComparableString implements Comparable { private String s; ComparableString(String s) { this.s = s; } public boolean less(ComparableString other) { return s.compareTo(other.s) < 0; } } 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; } } 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]))); } } class TreeUtils { static > Tree insertArray(Tree tree, A[] elems) { for (int i = 0; i < elems.length; i++) tree = tree.insert(elems[i]); return tree; } }