Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- List list1 = new ArrayList();
- list1.add("0");
- List list2 = new LinkedList();
- list2.add("1");
- list3.add("2");
- List list3 = new CompositeList(list1, list2...)
- assertEquals("0", list3.get(0));
- assertEquals("1", list3.get(1));
- assertEquals("2", list3.get(2));
- /**
- * A list composed of zero to many child lists. Additions occur in the first
- * acceptable list: if an insertion is attempted at an index that lies on a break
- * between lists, the insert occurs in the first list. Modifications are undefined
- * if list of lists has no elements.
- * @param <T> Type of element stored in list.
- */
- public class CompositeList<T> extends AbstractList<T> {
- // member variables -------------------------------------------------------------------
- private Collection<List<T>> mLists;
- // constructors -----------------------------------------------------------------------
- public CompositeList(Collection<List<T>> pLists) {mLists = pLists;}
- // methods ----------------------------------------------------------------------------
- /** Sum of sizes of component lists. */
- 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());
- }
- /**
- * If add could occur at end of one list or beginning of the next, the former
- * behavior is guaranteed.
- */
- @Override public void add(int pIdx, T pElement) {
- if (pIdx == 0) {
- mLists.iterator().next().add(0, pElement);
- } else {
- // find prior object
- 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);
- // don't auto-box because remove(Object) and remove(int) can be confused
- 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);
- }
- /** More efficient than superclass implementation. */
- @Override public Iterator<T> iterator() {
- return Iterators.concat(
- Collections2.transform(mLists, Collection::iterator).iterator()
- );
- }
- @Override public void clear() {mLists.forEach(Collection::clear);}
- /**
- * Identify list and index that composite index refers to. For
- * [A], [], [], [B, C]; composite index 1 would return the fourth list
- * mapped to the number 0.
- */
- private Map.Entry<List<T>,Integer> findIndex(int pCompositeIdx) {
- // composite index of list's starting point
- 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());
- }
- }
Add Comment
Please, Sign In to add comment