最多2个对象的Java集

时间:2018-03-15 11:17:56

标签: java data-structures

我正在编写一个返回Set<String>的方法。该集合可能包含0,1或2个对象。字符串键也很小(最多8个字符)。然后在紧密循环中使用该集合,其中多次迭代调用contains()

对于0个对象,我会返回Collections.emptySet()

对于1个对象,我将返回Collections.singleton()

对于2个对象(最大可能的数字),HashSet似乎有点过分。难道没有更好的结构吗?也许TreeSet略好一点?不幸的是,我仍在使用Java 7 :-(因此无法使用像Set.of()这样的现代内容。

2个字符串的数组可能会提供最佳性能,但这不是Set。我希望代码能够自我记录,所以我真的想要返回一个Set,因为这是所需的逻辑接口。

3 个答案:

答案 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)

您可以通过

实现这一目标
  • 创建一个实现Set interface
  • 的类
  • 覆盖添加和删除方法
  • 通过super.add(E element)
  • 在课程初始化时添加值
  • 使用该课程