任何比较条件 returns 错误值

Any comparasion condition returns bad value

我在尝试比较两个整数时遇到了非常奇怪的行为,但首先要做的是。这是我在 class:

中的方法
public class CollectionsTutorial {
    private Collection<String> collection = null;
    
    public CollectionsTutorial() {
        this.collection = new ArrayList<String>();
        
        for(int i=0;i<100000;i++) {
            collection.add("item_"+((i+1)%10000));
        }
    }
    
    public Set<String> getSet(){
        HashSet<String> set = new HashSet<String>(10000);
        for(String item: this.collection) {
            if (!set.contains(item)) {
                set.add(item);
            }
        }
        return set;
    }

    public TreeSet<String> getEvery3ElementAsSortedSet(){
        TreeSet<String> tree = new TreeSet<String>();
        int counter = 0;
        for(String item : this.collection) {
            if (counter%2==0) {
                tree.add(item);
                counter = -1;
            }
            counter++;
        }
        return tree;
    }
}

整个 class 在这里并不重要 - 它只包含 ArrayList<String>。我需要 return 树中的每 3 个元素,一切顺利,直到比较当前计数器值的时候。 return 每次都是如此。我确信它是因为在测试时它正在将集合的每个元素添加到树中。我试过使用 compareTo()equalsTo()valueOf()intValue(),但没有任何帮助。

编辑。 我已将代码更改为 class 视图 - 也许是其他原因导致错误?

这是我要通过的测试

public class CollectionsTutorialTest {

    @Test
    public void GetEvery3ElementTest() {
        CollectionsTutorial testObj = new CollectionsTutorial();
        TreeSet<String> tree = new TreeSet<String>();
        tree.addAll(testObj.getSet() );
        assertEquals(false, tree.contains("item_2"));
    }
    
}

“我需要 return 树中的每 3 个元素...”此描述为 modulo % operator 尖叫。

如果您想在每 3 次迭代时输入 if 条件,则可以使用以下条件进行检查:counter % 3 == 0。您根本不需要减去任何东西。

% 是如何工作的?

简单地说:模运算符return是除法的结果。

示例:

5 / 3 = 1 with remain 2
5 % 3 = 2 

9 / 3 = 3 with remain 0 
9 % 3 = 0

注:

if (counter % 2 == 0) {
    tree.add(item);
    counter = -1;
}
counter++;

您使用counter % 2 == 0。这将为第二个元素 return true。之后设置 counter = -1 是因为您打算获取每个第 3 个元素。但是,这不起作用。

原因如下:

System.out.println(0 % 1);        // 0 % 1 = 0
System.out.println(0 % 2);        // 0 % 2 = 0
System.out.println(0 % 3);        // 0 % 3 = 0
System.out.println(0 % 4);        // 0 % 4 = 0

如您所见,每次 counter 达到值 0 时,无论除数如何,if 条件都将结果为真。这就是你使用 % 3.

的原因

列表创建者:

        for(int i=0;i<100_000;i++) {
            collection.add("item_"+((i+1)%10_000));
        }

导致:

   collection[0] = item_1
   collection[1] = item_2
   collection[2] = item_3
   collection[3] = item_4
   ...
   collection[9_998] = item_9999
   collection[9_999] = item_0         // (9_999+1) % 10_000 is 0
   collection[10_000] = item_1        // (10_000+1) % 10_000 is 1
   collection[10_001] = item_2
   collection[10_002] = item_3     
   collection[10_003] = item_4    
   ...
   collection[19_998] = item_9999      // (19_998+1) % 10_000 is 9_999
   collection[19_999] = item_0         // (19_999+1) % 10_000 is 0
   collection[20_000] = item_1
   collection[20_001] = item_2
   collection[20_002] = item_3
   collection[20_003] = item_4
   ...

以上不是代码

现在请注意 20_001 % 30 - 所以第三个 item_2 将被选中; 50_001 % 380_001 % 3 也是如此。因此,实际上该项目 添加 3 次到 (因为它是 Set,只有一个实例是 保持)。最后,每个 item 的一个版本将出现在结果中。类似于 counter%3 == 1counter%3 == 2(基本上是有问题的第一个代码版本。)

教训:检查 item_2 是否存在,不会每次都检查条件 "returns 是否为真".


更好 测试:

        ...
        int index = 0;  // DEBUG
        for(String item : this.collection) {
            if (counter%2==0) {
                System.out.println(index);  // DEBUG
                tree.add(item);
                counter = -1;
            }
            index += 1;  // DEBUG
            ...

以上不是完整代码,只是展示测试的想法


奖金:
Set 保存 重复项(“不包含重复元素的集合”),在下面的代码段中:

            if (!set.contains(item)) {
                set.add(item);
            }

if 不是必需的 - add()

已经检查过了