IntCharSet implements Iterable<Integer> { @SuppressWarnings("ReferenceEquality") public void sub(IntCharSet set) { if (DEBUG) { Out.dump("complement"); Out.dump("this : " + this); Out.dump("other : " + set); assert invariants(); assert set.invariants(); assert isSubSet(set, this); assert set != this; } int i = 0; int j = 0; int setSize = set.intervals.size(); while (i < intervals.size() && j < setSize) { Interval x = this.intervals.get(i); Interval y = set.intervals.get(j); if (DEBUG) { Out.dump("this : " + this); Out.dump("this [" + i + "] : " + x); Out.dump("other [" + j + "] : " + y); } if (x.end < y.start) { i++; continue; } if (y.end < x.start) { j++; continue; } if (x.start == y.start && x.end == y.end) { intervals.remove(i); j++; continue; } if (x.start == y.start) { x.start = y.end + 1; j++; continue; } if (x.end == y.end) { x.end = y.start - 1; i++; j++; continue; } intervals.add(i, new Interval(x.start, y.start - 1)); x.start = y.end + 1; i++; j++; } if (DEBUG) { Out.dump("result: " + this); assert invariants(); } }  static IntCharSet of(Interval interval); static IntCharSet of(Interval... intervals); static IntCharSet ofCharacterRange(int start, int end); static IntCharSet ofCharacter(int singleChar); static IntCharSet allChars(); static IntCharSet nlChars(); @SuppressWarnings("ReferenceEquality") void add(IntCharSet set); @SuppressWarnings("IncrementInForLoopAndHeader") void add(Interval interval); void add(int c); boolean contains(int singleChar); boolean contains(IntCharSet other); @Override boolean equals(Object o); @Override int hashCode(); IntCharSet and(IntCharSet set); @SuppressWarnings("ReferenceEquality") void sub(IntCharSet set); static IntCharSet complementOf(IntCharSet x); boolean containsElements(); int numIntervals(); List<Interval> getIntervals(); Iterator<Interval> intervalIterator(); IntCharSet getCaseless(UnicodeProperties unicodeProperties); @Override String toString(); static IntCharSet copyOf(IntCharSet intCharSet); int size(); @Override IntCharSetIterator iterator();  }
@Test public void sub() { IntCharSet a = IntCharSet.of(new Interval(1, 7), new Interval(10, 42)); a.sub(IntCharSet.ofCharacterRange(4, 7)); a.sub(IntCharSet.ofCharacterRange(10, 41)); assertThat(a).isEqualTo(IntCharSet.of(new Interval(1, 3), Interval.ofCharacter(42))); }