【发布时间】:2015-09-13 09:51:15
【问题描述】:
我正在尝试编写Set 的实现,它有一个附加方法randomElement(),它从Set 中随机返回一个元素。我基于HashSet 实现了快速contains() 方法。我还使用了ArrayList,因此randomElement() 方法也是O(1) - 使用ArrayList,您所要做的就是选择一个随机索引。
这是我的代码。
public final class RandomChoiceSet<E> extends AbstractSet<E> {
private final List<E> list = new ArrayList<>();
private final Set<E> set = new HashSet<>();
private final Random random = new Random();
public RandomChoiceSet() {}
public RandomChoiceSet(Collection<? extends E> collection) {
addAll(collection);
}
public E randomElement() {
return list.get(random.nextInt(list.size()));
}
@Override
public int size() {
return list.size();
}
@Override
public boolean contains(Object o) {
return set.contains(o);
}
@Override
public void clear() {
list.clear();
set.clear();
}
@Override
public boolean add(E e) {
boolean result = set.add(e);
if (result)
list.add(e);
return result;
}
@Override
public boolean remove(Object o) {
boolean result = set.remove(o);
if (result)
list.remove(o);
return result;
}
@Override
public Iterator<E> iterator() {
return new Iterator<E>() {
private final Iterator<E> iterator = list.iterator();
private E e;
@Override
public boolean hasNext() {
return iterator.hasNext();
}
@Override
public E next() {
return e = iterator.next();
}
@Override
public void remove() {
iterator.remove();
set.remove(e);
}
};
}
}
维护List 和Set 的缺点是它使remove() 方法成为O(n),因为必须首先在ArrayList 中找到该元素,然后所有其他元素都有沿一个地方移动。所以我想知道是否可以写这样一个Set,其中所有五个操作size()、contains()、add()、remove() 和randomElement() 都是O(1)?
【问题讨论】:
-
我不确定复制数据是否是个好主意。
HashSet和ArrayList已经引入了足够的内存开销 -
@Dici 是的。我主要想知道这在理论上是否可行。
-
我明白了。我也想知道,看来您正在寻找无法以有效方式同时实现的属性
标签: java collections set time-complexity