. Guava iterator(), .
public class CompositeList<T> extends AbstractList<T> {
private Collection<List<T>> mLists;
public CompositeList(Collection<List<T>> pLists) {mLists = pLists;}
public int size() {return mLists.stream().mapToInt(Collection::size).sum();}
@Override public T get(int pIdx) {
final Map.Entry<List<T>,Integer> m = findIndex(pIdx);
return m.getKey().get(m.getValue());
}
@Override public void add(int pIdx, T pElement) {
if (pIdx == 0) {
mLists.iterator().next().add(0, pElement);
} else {
final Map.Entry<List<T>,Integer> m = findIndex(pIdx - 1);
m.getKey().add(m.getValue() + 1, pElement);
}
}
@Override public T remove(int pIdx) {
final Map.Entry<List<T>,Integer> m = findIndex(pIdx);
return m.getKey().remove(m.getValue().intValue());
}
@Override public T set(int pIdx, T pElement) {
final Map.Entry<List<T>,Integer> m = findIndex(pIdx);
return m.getKey().set(m.getValue(), pElement);
}
@Override public Iterator<T> iterator() {
return Iterators.concat(
Collections2.transform(mLists, Collection::iterator).iterator()
);
}
@Override public void clear() {mLists.forEach(Collection::clear);}
private Map.Entry<List<T>,Integer> findIndex(int pCompositeIdx) {
int listStart = 0;
for (final List<T> list : mLists) {
if (listStart + list.size() > pCompositeIdx) {
return new AbstractMap.SimpleImmutableEntry<>(
list, pCompositeIdx - listStart
);
}
listStart += list.size();
}
throw new IndexOutOfBoundsException(pCompositeIdx + " >= " + size());
}
}