09 November 2016

Null is Not Typed

It is ambiguous if a typed null in Java is passed to a method in Groovy.

List Comparison

When comparing two lists, Java checks the equality for each element by calling equals() to compare. However, Groovy compares lists by calling compareTo() for each element such that the results may differ because two unequal items can be compared as the same. This gotcha causes implicity bugs and breaks legacy Java code.

import java.util.*;

public class Item implements Comparable<Item> {
  int offset;
  int size;
  public Item(int offset, int size) {
    this.offset = offset;
    this.size = size;
  }

  @Override
  public int compareTo(Item item) {
    System.out.println("Item.compareTo() called");
    return Integer.compare(offset, item.offset);
  }

  @Override
  public boolean equals(Object o) {
    System.out.println("Item.equal() called");
    if(o instanceof Item) {
      Item that = (Item)o;
      return offset == that.offset && size == that.size;
    }
    return false;
  }

  public static void main(String[] argv) {
    Item item1 = new Item(0, 1);
    Item item2 = new Item(0, 2);
    List<Item> list1 = new ArrayList<>();
    List<Item> list2 = new ArrayList<>();
    list1.add(item1);
    list2.add(item2);

    // Java totally disagrees but Groovy agrees upon == and equals() for lists
    assert list1 == list2;
    assert list1.equals(list2);
    assert list1.is(list2);
  }
}