实现了Iterable hands错误的尺寸

时间:2017-08-21 23:29:52

标签: java

我是这个网站的新手,所以如果我的问题或问题的风格有任何问题,请随时纠正我。

我需要在我的ShareCollection类中实现Iterable接口,这样我就可以迭代这个类中的所有共享。当我使用样本数据测试我的班级时,它总是会回拨“0' 0作为大小,即使(在我的例子中)我的收藏中有两个份额。

以下是该类的代码+一个回复错误的示例方法:

public class ShareCollection implements Iterable<Share>{
    private HashSet<Share> shares;

    public ShareCollection() {
        this.shares = new HashSet<Share>();
    }

    public ShareCollection(Collection<Share> shares) {
        for (Share s : shares) {
            HashSet<Share> checkSet = new HashSet<Share>(shares);
            checkSet.remove(s);
            if (checkSet.contains(s)) {
                throw new IllegalArgumentException("There can't be two shares with the same name!");
            }
        }
        this.shares = new HashSet<Share>(shares);
    }

    public boolean add(Share share) {
        if (share == null) {
            throw new NullPointerException("share isnt allowed to be null!");
        }
        return shares.add(share);
    }


    @Override
    public Iterator<Share> iterator() {
        return new HashSet<Share>(shares).iterator();
    }
}

以下是使用以下示例数据的主要方法:

public static void main(String[] args) {
    Share s1 = new Share("s1", new ArrayList<>());
    Share s2 = new Share("s2", new ArrayList<>());

    ShareCollection sc = new ShareCollection()
    sc.add(s1);
    sc.add(s2);

    int counter = 0;

    for (Share s : sc) {
        counter++;
    }

    System.out.print("Counter: " + counter + "\n");
    System.out.print("Size: " + sc.size());

}

以下是主方法的输出:

Counter: 2
Size: 0

以下是&#39;添加&#39; -method的错误:

java.lang.AssertionError: ShareCollection#size should give 1 for a collection with 1 elements.
Expected: <1>
     but: was <0>
    at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
    at org.junit.Assert.assertThat(Assert.java:956)
    at jpp.marketanalysis.tests.data.TestShareCollection.hasElements(TestShareCollection.java:158)
    at jpp.marketanalysis.tests.data.TestShareCollection.testAdd(TestShareCollection.java:55)

提前感谢您的回答!

更新

  • 使用HashSet交换ArrayList(参见@ SeanPatrickFloyd&#39;第一个答案)

1 个答案:

答案 0 :(得分:0)

可能的错误:您的Share类是否覆盖.equals()方法? 因为ArrayList.contains()委托给.equals()

此外,我发现您的代码至少存在两个问题:

  • 在.contains()查找(O(n))中,ArrayList非常糟糕。您应该使用HashSet(在这种情况下,您需要覆盖.equals()类中的.hashCode()Share),它会为您提供O(1)并处理适合您的.add()方法
  • 你要返回的迭代器是ArrayList的原始迭代器,它使你的代码在几个方面容易受到攻击,包括ConcurrentModificationException如果你在迭代时添加一些东西,还有变异,如果有人调用{{1}在迭代器上。我建议您制作该集合的防御副本并使用该迭代器。

此处您的代码已相应重写:

.remove()