package com.tofvesson.collections; import java.util.ArrayList; import java.util.Collection; import java.util.List; import static com.tofvesson.collections.Empty.empty; @SuppressWarnings({"unchecked", "ReturnOfInnerClass", "unused"}) public class ShiftingList implements List { /** * Holder for entries. Dur to reasons, the array holds objects. */ Object[] entries; /** * Populated entries. */ int pop = 0; /** * Maximum size of set. */ public final int maxSize; /** * Load factor used when calculating how to resize array. */ protected final float load; public ShiftingList(int maxSize, float load){ this.maxSize = maxSize<1?20:maxSize; this.load = load>0.99||load<0.1?0.75f:load; entries = new Object[1]; } public ShiftingList(int maxSize){ this(maxSize, 0.75f); } public int size() { return pop; } public boolean isEmpty() { return pop==0; } public boolean contains(Object o) { if(o==empty) return false; for(int i = 0; i T[] toArray(T[] a) { for(int i = 0; i c) { boolean b = true; for(Object o : c) b &= contains(o); return b; } public boolean addAll(Collection c) { ArrayList l = new ArrayList(); for(E e : c) if(!contains(e)) l.add(e); if(l.size()>maxSize) for(int i = maxSize; i c) { if(index>=maxSize) return false; if(index>=entries.length || index<0 || c.size()==0) return false; ArrayList l = new ArrayList(); for(E e : c) if(!contains(e)) l.add(e); if(index+l.size()>maxSize) for(int i = maxSize-index; i= maxSize ? pop : pop+l.size(); if(l.size()+index c) { int removed = 0; for(int i = 0; i c) { int removed = 0; for(int i = 0; ientries.length) adaptLoad(accountFor); // If new elements exceed limit, adapt load if(accountFor>entries.length) return; // No need to delete elements if new values exceed limit System.arraycopy(entries, 0, entries, accountFor, entries.length-accountFor); // Shift array elements to account for new elements } public E get(int i){ if(i>pop) return null; return entries[i]==empty?null:(E)entries[i]; } public E set(int index, E element) { if(index > pop) return null; E e = get(index); entries[index] = element==null?empty:element; return e; } public void add(int index, E element) { if(index<0 || contains(element)) return; Object o = element==null?empty:element; pop = pop==maxSize?pop:pop+1; adaptLoad(); if((index>=entries.length?index=Math.min(entries.length-1, pop):index)==entries.length-1){ entries[index] = o; return; } System.arraycopy(entries, index, entries, index+1, entries.length-(index+1)); entries[index] = o; } public E remove(int index) { if(index>pop || index<0) return null; E e = entries[index]==empty?null:(E)entries[index]; entries[index] = null; shift(); if(--pop0; --i) if(o.equals(entries[i])) return i; return -1; } public Iterator iterator(){ return new Iterator(this); } public ListIterator listIterator(){ return new ListIterator(this); } public ListIterator listIterator(int index) { if(index<0) throw new RuntimeException("Invalid starting point for iterator defined: "+index); return new ListIterator(this, index); } public List subList(int fromIndex, int toIndex) { if(fromIndex<0 || fromIndex>=toIndex || fromIndex>pop || toIndex>pop) return new ArrayList(); ShiftingList l = new ShiftingList(maxSize); for(int i = toIndex-1; i>fromIndex; --i) l.add(entries[i]==empty?null:(E)entries[i]); return l; } /** * Standard iterator. For observing list. * @param Type of object stored in list. */ public static class Iterator implements java.util.Iterator{ protected int counter = 0; private final ShiftingList ref; private Object previous; public Iterator(ShiftingList ref){ this.ref = ref; } public boolean hasNext() { return counter Type of object stored in list. */ public static class ListIterator implements java.util.ListIterator{ protected int counter = 0; protected boolean opNxt = false; private Object pEl = null; private final int pop; private final Object[] entries; private final ShiftingList list; public ListIterator(ShiftingList list){ this.pop = list.pop; this.entries = list.entries; this.list = list;} public ListIterator(ShiftingList list, int start){ this(list); counter = start; } public boolean hasNext() { return counter0&&pop!=0; } public V previous() { opNxt = false; return (V)(pEl=entries[--counter]==empty?null:entries[counter]); } public int nextIndex() { return counter+1