【问题标题】:MultiSet: problems with add, remove and equalsMultiSet:add、remove 和 equals 的问题
【发布时间】:2012-01-16 19:53:54
【问题描述】:

我的 MultiSet 类的一些方法存在一些问题。 这是一个测试器,MultiSet 类应该得到输出:“Succes!”如果它工作正常。 这是测试仪:

public class MultiSetTest {

    public static void main(String[] args) {
    MultiSet<String> a = new MultiSet<String>();
    MultiSet<String> b = new MultiSet<String>();

    a.add("Foo");
    a.add("Bar");
    a.add("Foo");
    System.out.println("a:" + a); // test toString

    b.add("Bar");
    b.add("Foo");
    b.add("Bar");
    b.add("Foo");
    System.out.println("b:" + b);

    assert !a.equals(b) : "Failed test 1!"; // test equals
    assert b.remove("Bar") : "Failed test 2!"; // test remove
    assert a.equals(b) : "Failed test 3!";
    for(String s : a) { // test iterator
        assert b.remove(s) : "Failed test 4!";
    }
    assert b.size() == 0 : "Failed test 5!";

    Set<String> baseSet = new HashSet<String>(a);
    assert baseSet.size()==2 : "Failed test 6!";  

    b = new MultiSet<String>(a);
    assert a.equals(b) : "Failed test 7!";

    try {
        assert false;
        System.out.println("Please enable assertions!");
    }
    catch(AssertionError e) {
        System.out.println("Success!");
    }
    }
}

还有我的 Multiset 类:

public class MultiSet<E> extends AbstractCollection<E>
{
    private int size = 0;
    private Map<E, Integer> values = new HashMap<E, Integer>();

    public MultiSet()
    {

    }

    public MultiSet(Collection<E> c)
    {
        addAll(c);
    }

    public boolean add()
    {
        return false;
    }

    public boolean remove()
    {
        return false;
    }

    public Iterator<E> iterator()
    {
        return new Iterator<E>()
        {
            private Iterator<E> iterator = values.keySet().iterator();
            private int remaining = 0;
            private E current = null;

            public boolean hasNext()
            {
                return remaining > 0 || iterator.hasNext();
            }

            public E next()
            {
                if (remaining == 0)
                {
                    current = iterator.next();
                    remaining = values.get(current);
                }
                remaining--;
                return current;
            }
            public void remove()
            {
                throw new UnsupportedOperationException();
            }
        };
    }

        public boolean equals(Object object)
        {
            if (this == object) return true;
            if (this == null) return false;
            if (this.getClass() != object.getClass()) return false;
            MultiSet<E> o = (MultiSet<E>) object;
            return o.values.equals(values);
        }


        public int hashCode()
        {
            return values.hashCode()*163 + new Integer(size).hashCode()*389;
        }

        public String toString()
        {
            String res = "";
            for (E e : values.keySet());
                    //res = ???;
            return getClass().getName() + res;
        }

        public int size()
        {
            return size;
        }
    }

如果你能在添加或删除的过程中帮助我,那么我可能会解决另一个问题。

另外,我的 equals 似乎无法正常工作, 而且我不确定如何在 String toString 上计算出“res”。不要介意我的退货声明,稍后我会加上一些括号等以使其看起来不错。

感谢您的帮助。 // 克里斯

【问题讨论】:

  • 您应该显示您尝试添加/删除的内容。您还应该准确说明出了什么问题。此外,您还有一个看起来完全没用的 size 变量。
  • 从我的 MultiSet 中添加/删除对象

标签: java multiset


【解决方案1】:

为什么不使用经过充分测试的 Google Guavas's Multisets 而不是重新发明轮子?您可以选择多种实现之一:

  • ConcurrentHashMultiset,
  • EnumMultiset,
  • ForwardingMultiset,
  • HashMultiset,
  • 不可变多集,
  • LinkedHashMultiset,
  • TreeMultiset

什么应该涵盖您的用例,或者 - 如果您真的想要 - 自己实现 Multiset 接口,查看默认实现的来源。

编辑:

您的实现违反了Collecion 接口契约——您不能为add(E e) 返回false。阅读Collection docs

boolean add(E e)

参数:

e - 要确保在此集合中存在的元素

返回:

true 如果此集合因调用而改变

投掷:

UnsupportedOperationException - 如果此集合不支持添加操作

如果您想使用只读多重集,请使用ImmutableMultiset(更具体地说是ImmutableMultiset.copyOf(Iterable))或实现Multiset 的接口add(E e)方法抛出UnsupportedOperationException

【讨论】:

  • 我浏览了其中的一些。那么,这会奏效吗? @Override public boolean add(E o){ throw new UnsupportedOperationException(); } 对于我的添加方法?
  • 我编辑了我的答案以回应这条评论 - 基本上你不能从 add 方法返回 false,它违反了 Collection 合同。
猜你喜欢
  • 2012-01-17
  • 1970-01-01
  • 2014-06-24
  • 2011-08-25
  • 2011-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-13
相关资源
最近更新 更多