Java « Создание собственного Set
Добрый день комрады. Такой вопрос к знатокам - нужно создать собственное множество Set, всегда упорядоченное по возрастанию значений toString() и максимально быстро выполняющее операцию contains(...). Насчет упорядочивания - все понятно, переопределяем compare. А вот насчет одновременного выполнения быстрого contains() и постоянно упорядоченного множества - вот тут проблема. С быстрым contains() лучше расширить HashSet и все. С постоянным упорядочиванием - TreeSet. В этом и загвоздка.
Я знаю, что и то и то реализуется на Map(HashMap или TreeMap), но они private, и в случае расширения я не смогу упорядочить HashMap вручную. Как быть? Не уж то наследоваться от AbstractSet и реализовывать все вручную?
Update: по памяти нет ограничений, т.е. теоретически можно включить в новое множество приватный член 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.
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.