Java « Создание собственного Set

Добрый день комрады. Такой вопрос к знатокам - нужно создать собственное множество Set, всегда упорядоченное по возрастанию значений toString() и максимально быстро выполняющее операцию contains(...). Насчет упорядочивания - все понятно, переопределяем compare. А вот насчет одновременного выполнения быстрого contains() и постоянно упорядоченного множества - вот тут проблема. С быстрым contains() лучше расширить HashSet и все. С постоянным упорядочиванием - TreeSet. В этом и загвоздка.

Я знаю, что и то и то реализуется на Map(HashMap или TreeMap), но они private, и в случае расширения я не смогу упорядочить HashMap вручную. Как быть? Не уж то наследоваться от AbstractSet и реализовывать все вручную?

Update: по памяти нет ограничений, т.е. теоретически можно включить в новое множество приватный член TreeSet.

1 ответов


Если отбросить странное требование относительно метода toString и принять во внимание отсутствие ограничения на память, можно попробовать взять лучшее от обоих коллекций с помощью композиции. То есть, сделать примерно так.

import java.util.*;

public class FastSet<E> implements Set<E> {

    private final Set<E> hashSet = new HashSet<E>();
    private final Set<E> treeSet;

    public FastSet() {
        treeSet = new TreeSet<E>();
    }

    public FastSet(Comparator<E> comparator) {
        treeSet = new TreeSet<E>(comparator);
    }

    @Override
    public int size() {
        return hashSet.size();
    }

    @Override
    public boolean isEmpty() {
        return hashSet.isEmpty();
    }

    @Override
    public boolean contains(Object o) {
        return hashSet.contains(o);
    }

    @Override
    public Iterator<E> iterator() {
        return treeSet.iterator();
    }

    @Override
    public Object[] toArray() {
        return treeSet.toArray();
    }

    @Override
    public <T> T[] toArray(T[] a) {
        return treeSet.toArray(a);
    }

    @Override
    public boolean add(E e) {
        treeSet.add(e);
        return hashSet.add(e);
    }

    @Override
    public boolean remove(Object o) {
        treeSet.remove(o);
        return hashSet.remove(o);

    }

    @Override
    public boolean containsAll(Collection<?> c) {
        return hashSet.containsAll(c);
    }

    @Override
    public boolean addAll(Collection<? extends E> c) {
        treeSet.addAll(c);
        return hashSet.addAll(c);
    }

    @Override
    public boolean retainAll(Collection<?> c) {
        treeSet.retainAll(c);
        return hashSet.retainAll(c);
    }

    @Override
    public boolean removeAll(Collection<?> c) {
        treeSet.removeAll(c);
        return hashSet.removeAll(c);
    }

    @Override
    public void clear() {
        treeSet.clear();
        hashSet.clear();
    }
}

Однако, надо эту имплементацию протестировать в реальных условиях. Не ручаюсь за то, что она корректна. Если объект типа Comparator передаётся явно, то на элементы ограничения не налагаются. Если не передан, то элементы должны имплементить Comparable.