/** * */ package net.varkhan.base.containers.list; import net.varkhan.base.containers.Index; import net.varkhan.base.containers.Indexable; import net.varkhan.base.containers.Iterable; import net.varkhan.base.containers.Iterator; import java.io.Externalizable; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; /** * <b>Constant-valued IndexedList.</b> * <p/> * An immutable IndexedList that returns a constant, predefined value for every * index. * <p/> * * @author varkhan * @date Mar 12, 2009 * @time 6:48:14 PM */ public class ConstIndexedList<Type> implements IndexedList<Type>, Externalizable, Cloneable { /** * An immutable IndexedList that always return a {@literal null} value for every index */ public static final ConstIndexedList<?> ConstNull=new ConstIndexedList<Object>(); private static final long serialVersionUID=1L; /** * The constant return value */ private Type defVal; /********************************************************************************** ** List constructors **/ /** * Builds a new constant IndexedList. * * @param def the constant entry value */ public ConstIndexedList(Type def) { defVal=def; } /** * Builds a new constant IndexedList, with a {@literal null} entry value. */ public ConstIndexedList() { defVal=null; } /********************************************************************************** ** List statistics accessors **/ /** * Returns the number of elements in this list. * * @return always 0 */ public long size() { return 0; } /** * Indicates whether this list is empty. * * @return {@literal true} */ public boolean isEmpty() { return true; } /** * Returns the smallest position higher that any valid index in this list. * * @return always 0 */ public long head() { return 0; } /** * Returns an index that has no associated element in this list. * * @return always 0 */ public long free() { return 0; } /** * Deletes all elements from this list */ public void clear() { } /** * Gets the default value * * @return the default value, returned by {@link #get} every time it is called */ public Type getDefaultValue() { return defVal; } /** * Sets the default value * * @param def the default value, returned by {@link #get} every time it is called */ public void setDefaultValue(Type def) { defVal=def; } /********************************************************************************** ** List entries accessors **/ /** * Indicates whether an index has an associated entry * * @param index a unique identifier for this entry * * @return always {@literal true} */ public boolean has(long index) { return true; } /** * Extracts the element designated by an index * * @param index a unique identifier for this entry * * @return the constant entry value */ public Type get(long index) { return defVal; } /** * Adds an element at the end of the list (in this implementation, * this method does nothing). * * @param val the object to store in the list * * @return always {@code 0} */ public long add(Type val) { return 0; } /** * Associates an element to a particular index (in this implementation, * this method does nothing). * * @param index a unique identifier for this entry * @param val the object to store in the list * * @return always {@code index} */ public long set(long index, Type val) { return index; } /** * Deletes an element, and invalidates the related index * * @param index a unique identifier for this entry */ public void del(long index) { } /********************************************************************************** ** List entries iterators **/ /** * Iterates over all indexes in the list, using an {@link Index}. * * @return an iterator over all the indexes that designate elements in the list */ public Index indexes() { return new Index() { public long current() { return 0; } public boolean hasNext() { return false; } public long next() { return 0; } public boolean hasPrevious() { return false; } public long previous() { return 0; } }; } /** * Iterates over all indexes in the collection. * * @return an empty iterable */ public java.lang.Iterable<Long> iterateIndexes() { return new java.lang.Iterable<Long>() { public java.util.Iterator<Long> iterator() { return new java.util.Iterator<Long>() { public boolean hasNext() { return false; } public Long next() { return 0L; } public void remove() { } }; } }; } /** * Iterates over all elements in the list. * * @return an empty iterator */ public Iterator<? extends Type> iterator() { return new Iterator<Type>() { public boolean hasNext() { return false; } public Type next() { return defVal; } public void remove() { } }; } /** * Iterate over each element of the list. * * @param vis the visitor * @param par the control parameter * @param <Par> the type of the control parameter * * @return {@code 0} */ public <Par> long visit(Visitor<Type,Par> vis, Par par) { return 0; } /** * Iterate over each element of the list. * * @param vis the visitor * @param par the control parameter * @param <Par> the type of the control parameter * * @return {@code 0} */ public <Par> long visit(IndexedVisitor<Type,Par> vis, Par par) { return 0; } /** * Iterates over a set of elements designated by an array of indexes. * * @param indexes an array of identifiers * * @return a constant-valued iterator over as many elements as there are indexes */ public Iterable<? extends Type> iterate(final long[] indexes) { return new Iterable<Type>() { public Iterator<Type> iterator() { return new Iterator<Type>() { private int i=0; public boolean hasNext() { return i<indexes.length; } public Type next() { i++; return defVal; } public void remove() { } }; } }; } /** * Iterates over a set of elements designated by an iterator over indexes. * * @param indexes an iterable over identifiers * * @return a constant-valued iterator over as many elements as there are indexes */ public Iterable<? extends Type> iterate(final java.lang.Iterable<Long> indexes) { return new Iterable<Type>() { public Iterator<Type> iterator() { return new Iterator<Type>() { private final java.util.Iterator<Long> iter=indexes.iterator(); public boolean hasNext() { return iter.hasNext(); } public Type next() { iter.next(); return defVal; } public void remove() { } }; } }; } /** * Iterates over a set of elements designated by an iterator over indexes. * * @param indexes an iterable over identifiers * * @return a constant-valued iterator over as many elements as there are indexes */ public Iterable<? extends Type> iterate(final Indexable indexes) { return new Iterable<Type>() { public Iterator<Type> iterator() { return new Iterator<Type>() { private final Index iter=indexes.indexes(); public boolean hasNext() { return iter.hasNext(); } public Type next() { iter.next(); return defVal; } public void remove() { } }; } }; } /********************************************************************************** ** Externalization **/ /** * Write a ConstIndexedList to a stream. * * @param out the stream to write the object to * * @throws IOException if I/O errors occur * @serialData {@code Object defVal} - the default value */ public void writeExternal(ObjectOutput out) throws IOException { out.writeObject(defVal); } /** * Read a ConstIndexedList from a stream. * * @param in the stream to read the object from * * @throws IOException if I/O errors occur */ @SuppressWarnings( { "unchecked" }) public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { defVal=(Type) in.readObject(); } /********************************************************************************** ** Object method overrides **/ /** * Return a hash code value for this list. * * @return the hash code of the default value, or {@code 0} if the default value is {@code null} */ public int hashCode() { return this.defVal==null ? 0 : this.defVal.hashCode(); } /** * Test whether two constant lists are equal. * * @return {@code true} iff {@code obj} is a ConstIndexedList and its default value is the same as this list */ public boolean equals(Object obj) { if(!(obj instanceof ConstIndexedList)) return false; ConstIndexedList<?> that=(ConstIndexedList<?>) obj; if(this.defVal==that.defVal) return true; // This OR is actually an exclusion, since we just compared the ref values if(this.defVal==null||that.defVal==null) return false; return this.defVal.equals(that.defVal); } /** * Return a clone of this list. * * @return an independent constant list, sharing the same default value */ @SuppressWarnings("unchecked") public ConstIndexedList<Type> clone() { ConstIndexedList<Type> clone=null; try { clone=(ConstIndexedList<Type>) super.clone(); } catch(CloneNotSupportedException e) { /** never happens **/} return clone; } /** * Returns a string representation of the list. * * @return the value of {@code "[ ("+ getDefaultValue() + ") ]"} */ public String toString() { return new StringBuilder().append("[ (").append(defVal).append(") ]").toString(); } }