OffsetLeadSeries extends OffsetSeries<T> { @Override public void copyTo(Object[] to, int fromOffset, int toOffset, int len) { int size = size(); if (fromOffset + len > size) { throw new ArrayIndexOutOfBoundsException(fromOffset + len); } int len1 = Math.max(0, Math.min(offset - fromOffset, len)); int len2 = len - len1; int off2 = fromOffset < offset ? 0 : fromOffset - offset; if (len1 > 0) { Arrays.fill(to, toOffset, toOffset + len1, filler); } if (len2 > 0) { delegate.copyTo(to, off2, toOffset + len1, len2); } } OffsetLeadSeries(Series<T> delegate, int offset, T filler); @Override Series<T> shift(int offset, T filler); @Override T get(int index); @Override void copyTo(Object[] to, int fromOffset, int toOffset, int len); @Override Series<T> materialize();  }
@Test public void testCopyTo() { Series<String> s = new OffsetLeadSeries<>(Series.forData("a", "b", "c", "d"), 1, "X"); Object[] b1 = new Object[5]; s.copyTo(b1, 0, 1, 4); assertArrayEquals(new Object[]{null, "X", "a", "b", "c"}, b1); Object[] b2 = new Object[5]; s.copyTo(b2, 1, 1, 3); assertArrayEquals(new Object[]{null, "a", "b", "c", null}, b2); Object[] b3 = new Object[5]; s.copyTo(b3, 3, 1, 1); assertArrayEquals(new Object[]{null, "c", null, null, null}, b3); Object[] b4 = new Object[5]; s.copyTo(b4, 0, 1, 1); assertArrayEquals(new Object[]{null, "X", null, null, null}, b4); }