Range { @Override public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof Range)) { return false; } Range range = (Range) o; return inclusiveStart == range.inclusiveStart && inclusiveEnd == range.inclusiveEnd && Objects.equals(start, range.start) && Objects.equals(end, range.end); } Range(T start, boolean inclusiveStart, T end, boolean inclusiveEnd); T getStart(); boolean isInclusiveStart(); T getEnd(); boolean isInclusiveEnd(); boolean isInRange(Object obj); @Override String toString(); @Override boolean equals(Object o); @Override int hashCode();  }
@Test public void testEquals() { assertTrue(new IdRange(null, null).equals(new IdRange(null, null))); assertTrue(new IdRange("a", null).equals(new IdRange("a", null))); assertTrue(new IdRange(null, "a").equals(new IdRange(null, "a"))); assertTrue(new IdRange("a", "b").equals(new IdRange("a", "b"))); assertFalse(new IdRange(null, null).equals(new IdRange("a", "c"))); assertFalse(new IdRange("a", null).equals(new IdRange(null, "a"))); assertFalse(new IdRange("a", "b").equals(new IdRange("a", "c"))); }