Лично я бы разработал это в терминах стандартного Set<>
интерфейса:
public class StringPair {
public StringPair(String a, String b) {
a_ = a;
b_ = b;
hash_ = (a_ + b_).hashCode();
}
public boolean equals(StringPair pair) {
return (a_.equals(pair.a_) && b_.equals(pair.b_));
}
@Override
public boolean equals(Object obj) {
if (obj instanceof StringPair) {
return equals((StringPair) obj);
}
return false;
}
@Override
public int hashCode() {
return hash_;
}
private String a_;
private String b_;
private int hash_;
}
public class StringSetImpl implements StringSet {
public StringSetImpl(SetFactory factory) {
pair_set_ = factory.createSet<StringPair>();
}
// ...
private Set<StringPair> pair_set_ = null;
}
Тогда вы можете оставить его на усмотрение пользователя StringSetImpl, чтобы использовать предпочтительный тип Set.Тем не менее, если вы пытаетесь оптимизировать доступ, это трудно сделать лучше, чем HashSet <> (по крайней мере, с точки зрения сложности времени выполнения), учитывая, что доступ равен O (1), тогда как для наборов на основе дерева есть O (log N).время доступа.
То, что содержит (), обычно возвращает true, может стоить рассмотреть Фильтр Блума , хотя для этого необходимо, чтобы было разрешено некоторое количество ложных срабатываний для метода has () (нене знаю, так ли это).
Редактировать
Чтобы избежать дополнительного выделения, вы можете сделать что-то подобное, что похоже на ваш двухуровневый подходза исключением использования набора, а не карты для второго уровня:
public class StringSetImpl implements StringSet {
public StringSetImpl() {
elements_ = new HashMap<String, Set<String>>();
}
public boolean contains(String a, String b) {
if (!elements_.containsKey(a)) {
return false;
}
Set<String> set = elements_.get(a);
if (set == null) {
return false;
}
return set.contains(b);
}
public void add(String a, String b) {
if (!elements_.containsKey(a) || elements_.get(a) == null) {
elements_.put(a, new HashSet<String>());
}
elements_.get(a).add(b);
}
public void remove(String a, String b) {
if (!elements_.containsKey(a)) {
return;
}
HashSet<String> set = elements_.get(a);
if (set == null) {
elements_.remove(a);
return a;
}
set.remove(b);
if (set.empty()) {
elements_.remove(a);
}
}
private Map<String, Set<String>> elements_ = null;
}
Поскольку сейчас я нахожусь в 4:20 утра, вышеописанное, безусловно, не самая лучшая моя работа (слишком утомленная, чтобы обновлятьсяобработка нуля этими различными типами коллекций), но это обрисовывает в общих чертах подход.