我正在编写一个返回Set<String>
的方法。该集合可能包含0,1或2个对象。字符串键也很小(最多8个字符)。然后在紧密循环中使用该集合,其中多次迭代调用contains()
。
对于0个对象,我会返回Collections.emptySet()
。
对于1个对象,我将返回Collections.singleton()
。
对于2个对象(最大可能的数字),HashSet
似乎有点过分。难道没有更好的结构吗?也许TreeSet
略好一点?不幸的是,我仍在使用Java 7 :-(因此无法使用像Set.of()
这样的现代内容。
2个字符串的数组可能会提供最佳性能,但这不是Set。我希望代码能够自我记录,所以我真的想要返回一个Set,因为这是所需的逻辑接口。
答案 0 :(得分:3)
使用AbstractSet
包装数组。假设您需要一个不可修改的集合,您只需要实现2个方法:
class SSet extends AbstractSet<String> {
private final String[] strings;
SSet(String[] strings) {
this.strings = strings;
}
@Override
public Iterator<String> iterator() {
return Arrays.asList(strings).iterator();
}
@Override
public int size() {
return strings.length;
}
}
如果需要,可以将Arrays.asList(strings)
存储在字段中,而不是String[]
。如果要将数组限制为该长度,也可以提供0,1和2-arg构造函数。
您还可以覆盖contains
:
public boolean contains(Object obj) {
for (int i = 0; i < strings.length; ++i) {
if (Objects.equals(obj, strings[i])) return true;
}
return false;
}
如果您不想创建一个只是创建迭代器的列表,您可以轻而易举地将其作为内部类实现:
class ArrayIterator implements Iterator<String> {
int index;
public String next() {
// Check if index is in bounds, throw if not.
return strings[index++];
}
public boolean hasNext() {
return index < strings.length;
}
// implement remove() too, throws UnsupportedException().
}
答案 1 :(得分:1)
然后在紧密循环中使用该集合,其中多次迭代调用contains()。
我可能会为此精简它。也许是这样的事情:
public static class TwoSet<T> extends AbstractSet<T> {
T a = null;
T b = null;
@Override
public boolean contains(Object o) {
return o.equals(a) || o.equals(b);
}
@Override
public boolean add(T t) {
if(contains(t)){
return false;
}
if ( a == null ) {
a = t;
} else if ( b == null ) {
b = t;
} else {
throw new RuntimeException("Cannot have more than two items in this set.");
}
return true;
}
@Override
public boolean remove(Object o) {
if(o.equals(a)) {
a = null;
return true;
}
if(o.equals(b)) {
b = null;
return true;
}
return false;
}
@Override
public int size() {
return (a == null ? 0 : 1) + (b == null ? 0 : 1);
}
@Override
public Iterator<T> iterator() {
List<T> list;
if (a == null && b == null) {
list = Collections.emptyList();
} else {
if (a == null) {
list = Arrays.asList(b);
} else if (b == null) {
list = Arrays.asList(a);
} else {
list = Arrays.asList(a, b);
}
}
return list.iterator();
}
}
答案 2 :(得分:0)
您可以通过
实现这一目标super.add(E element)