ReversedCharSequence extends ReverseIndexMapperBase implements ReverseCharSequence { @Override public ReversedCharSequence subSequence(int start, int end) { if (start < 0 || end > length()) throw new IndexOutOfBoundsException("[" + start + ", " + end + ") not in [0," + length() + "]"); final int startIndex = mapBoundary(end); final int endIndex = startIndex + end - start; return startIndex == myStartIndex && endIndex == myEndIndex ? this : new ReversedCharSequence(myChars, startIndex, endIndex); } @SuppressWarnings("WeakerAccess") private  ReversedCharSequence(CharSequence chars, int start, int end); @Override CharSequence getReversedChars(); int getStartIndex(); @Override IndexMapper getIndexMapper(); @Override int getEndIndex(); @Override int length(); @Override char charAt(int index); @Override ReversedCharSequence subSequence(int start, int end); @Override String toString(); @Override boolean equals(Object o); @Override int hashCode(); static ReversedCharSequence of(final CharSequence chars); static ReversedCharSequence of(final CharSequence chars, final int start); static ReversedCharSequence of(final CharSequence chars, final int start, final int end);  }
@Test public void subSequence() throws Exception { CharSequence orig = "abcdef"; CharSequence reved = "fedcba"; ReversedCharSequence test = (ReversedCharSequence) ReversedCharSequence.of(orig); int iMax = orig.length(); for (int i = 0; i < iMax; i++) { for (int j = iMax - i - 1; j >= 0 && j >= i; j--) { assertEquals("subSequence(" + i + "," + j + ")", reved.subSequence(i, j), test.subSequence(i, j).toString()); assertEquals("reverse.of(subSequence(" + i + "," + j + "))", orig.subSequence(test.mapIndex(j) + 1, test.mapIndex(j) + 1 + j - i), ReversedCharSequence.of(test.subSequence(i, j)).toString()); assertEquals("subSequence(" + i + "," + j + ").hashCode()", reved.subSequence(i, j).hashCode(), test.subSequence(i, j).hashCode()); assertEquals("subSequence(" + i + "," + j + ").equals()", true, test.subSequence(i, j).equals(reved.subSequence(i, j))); } } }