Search code examples
javaobjectcomparison

Any comparasion condition returns bad value


I struggle with very strange behaviour while trying to compare two ints but first things first. Here is my method inside the 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;
    }
}

The whole class doesn't really matter here - it only holds ArrayList<String>. I need to return every 3rd element in a tree and everything goes well until it's time to compare current counter value. It returns true everytime. I'm sure of it becouse while testing it's adding to the Tree every single element of collection. I've tried using compareTo(), equalsTo(), valueOf() and intValue() but nothing helps.

EDIT. I've change code to the class view - maybe something else is cousing the error?

Here is test i'm trying to pass

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"));
    }
    
}

Solution

  • "I need to return every 3rd element in a tree..." this description screams for the modulo % operator.

    If you want to enter an if-condition on every 3rd iteration then you can check this with the following condition: counter % 3 == 0. You don't need to subtract anything at all.

    How does % work?

    Put simply: The modulo operator returns the result of a division.

    Example:

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

    Note:

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

    You use counter % 2 == 0. This will return true for the second element. Afterwards you set counter = -1 because you intend to get every 3rd element. However, this does not work.

    Here's the reason why:

    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
    

    As you can see, every time your counter reaches the value 0 the if-condition will result in true regardless of the divisor. That's why you use % 3.