Tuesday, October 05, 2010

Comparing two Integers - don't expect auto-unboxing

If you wish to compare two Integers, explicitly compare their intValue(). Otherwise, what happens is an object comparison.

I was bitten by this as I was developing a test for a generic diff utility I had written. Here is the test code:


    public void test_diff_sets_rnd() {
        Random r = new Random();
        int n = r.nextInt(100);
        Set<Integer> set1 = new TreeSet<Integer>();
        Set<Integer> set2 = new TreeSet<Integer>();
        List<Integer> list = new ArrayList<Integer>();
        for (int i=0; i<n; i++) {
            int num = r.nextInt(100);
            set1.add(num);
            if (set2.add(num))
                list.add(num);
        }

        Set<Integer> removed = new TreeSet<Integer>();
        Set<Integer> added = new TreeSet<Integer>();

        n = set1.size()>0 ? r.nextInt(set1.size()) : 0;
        for (int i=0; i<n; i++) {
            int num = r.nextInt(set1.size());
            int remElt = list.get(num);
            if (set2.remove(remElt))
                removed.add(remElt);
        }

        n = r.nextInt(100);
        for (int i=0; i<n; i++) {
            int num = 100+r.nextInt(100);
            if (set2.add(num))
                added.add(num);
        }

        Pair<Set<Integer>, Set<Integer>> p = Utils.diff(set1,set2);

        System.out.println("set1:");
        for (Integer elt : set1) {
            System.out.print(elt + "\t");
        }
        System.out.println();

        System.out.println("set2:");
        for (Integer elt : set2) {
            System.out.print(elt + "\t");
        }
        System.out.println();

        System.out.println("added:");
        for (Integer elt : p.one) {
            System.out.print(elt + "\t");
        }
        System.out.println();

        System.out.println("removed:");
        for (Integer elt : p.two) {
            System.out.print(elt + "\t");
        }
        System.out.println();

        assertTrue(p.one.size()==added.size());
        assertTrue(p.two.size()==removed.size());

        for (Iterator<Integer> it1 = p.one.iterator(), it2 = added.iterator(); it1.hasNext();) {
            assertTrue(it1.next().intValue()==it2.next().intValue());
        }
        for (Iterator<Integer> it1 = p.two.iterator(), it2 = removed.iterator(); it1.hasNext();) {
            assertTrue(it1.next().intValue()==it2.next().intValue());
        }

    }

I had to use the intValue() explicitly in the last two for loops.

No comments: