Class UnmodifiableArrayList<E>

java.lang.Object
java.util.AbstractCollection<E>
java.util.AbstractList<E>
org.apache.sis.internal.util.UnmodifiableArrayList<E>
Type Parameters:
E - the type of elements in the list.
All Implemented Interfaces:
Serializable, Iterable<E>, Collection<E>, List<E>, RandomAccess, SequencedCollection<E>, CheckedContainer<E>
Direct Known Subclasses:
DefaultParameterDescriptorGroup.AsList, UnmodifiableArrayList.SubList

public class UnmodifiableArrayList<E> extends AbstractList<E> implements RandomAccess, CheckedContainer<E>, Serializable
An unmodifiable view of an array. Invoking is equivalent to except that this class uses one less level of indirection (which may be significant since unmodifiable lists are extensively used in SIS) and implements the CheckedContainer interface.

WARNING! Type safety hole

The getElementType() return type is Class<E>, but its implementation actually returns Class<? extends E>. This contract violation is possible because Java arrays are covariant (at the contrary of collections). In order to avoid such contract violation, callers must ensure that the type of array elements in exactly E, not a subtype of E. This class has no way to verify that condition. This class is not in the public API for this reason.

Note that the public API, Containers.unmodifiableList(Object[]), returns List<? extends E>, which is okay.

Since:
0.3
Version:
0.3
See Also:
  • Field Details

    • serialVersionUID

      private static final long serialVersionUID
      For compatibility with different versions.
      See Also:
    • array

      final E[] array
      The wrapped array.
  • Constructor Details

    • UnmodifiableArrayList

      protected UnmodifiableArrayList(E[] array)
      Creates a new instance wrapping the given array. A direct reference to the given array is retained (i.e. the array is not cloned). Consequently, the given array shall not be modified after construction if this list is intended to be immutable.

      This constructor is for sub-classing only. Users should invoke the wrap(Object[]) static method instead.

      The argument type is intentionally E[] instead of E... in order to force the caller to instantiate the array explicitly, in order to make sure that the array type is the intended one.

      WARNING! Type safety hole

      Callers must ensure that the type of array elements in exactly E, not a subtype of E. See class javadoc for more information.
      Parameters:
      array - the array to wrap.
  • Method Details

    • wrap

      public static <E> UnmodifiableArrayList<E> wrap(E[] array)
      Creates a new instance wrapping the given array. A direct reference to the given array is retained (i.e. the array is not cloned). Consequently, the given array shall not be modified after construction if the returned list is intended to be immutable.

      WARNING! Type safety hole

      Callers must ensure that the type of array elements in exactly E, not a subtype of E. If the caller is okay with List<? extends E>, then (s)he should use Containers.unmodifiableList(Object[]) instead. See class javadoc for more information.

      The argument type is intentionally E[] instead of E... in order to force the caller to instantiate the array explicitly, in order to make sure that the array type is the intended one.

      Type Parameters:
      E - the type of elements in the list.
      Parameters:
      array - the array to wrap, or null if none.
      Returns:
      the given array wrapped in an unmodifiable list, or null if the given array was null.
    • wrap

      public static <E> UnmodifiableArrayList<E> wrap(E[] array, int lower, int upper)
      Creates a new instance wrapping a subregion of the given array. A direct reference to the given array is retained (i.e. the array is not cloned). Consequently, the specified sub-region of the given array shall not be modified after construction if the returned list is intended to be immutable.

      This method does not check the validity of the given index. The check must be done by the caller.

      WARNING! Type safety hole

      Callers must ensure that the type of array elements in exactly E, not a subtype of E. If the caller is okay with List<? extends E>, then (s)he should use Containers.unmodifiableList(Object[]) instead. See class javadoc for more information.
      Type Parameters:
      E - the type of elements in the list.
      Parameters:
      array - the array to wrap.
      lower - low endpoint (inclusive) of the sublist.
      upper - high endpoint (exclusive) of the sublist.
      Returns:
      the given array wrapped in an unmodifiable list.
    • getElementType

      public Class<E> getElementType()
      Returns the element type of the wrapped array. The default implementation returns array.getClass().getComponentType().
      Specified by:
      getElementType in interface CheckedContainer<E>
      Returns:
      the type of elements in the list.
    • lower

      int lower()
      Returns the index of the first valid element. To be overridden by UnmodifiableArrayList.SubList only.
    • size

      public int size()
      Returns the list size.
      Specified by:
      size in interface Collection<E>
      Specified by:
      size in interface List<E>
      Specified by:
      size in class AbstractCollection<E>
      Returns:
      the size of this list.
    • arraySize

      public final int arraySize()
      Returns the size of the array backing this list. This is the length of the array given to the constructor. It is equal to size() except if this instance is a sublist, in which case the value returned by this method is greater than size().

      This method can be used as a hint for choosing a UnmodifiableArrayList instance to keep when there is a choice between many equal instances. Note that a greater value is not necessarily more memory consuming, since the backing array may be shared by many sublists.

      Returns:
      the length of the backing array.
    • get

      public E get(int index)
      Returns the element at the specified index.
      Specified by:
      get in interface List<E>
      Specified by:
      get in class AbstractList<E>
      Parameters:
      index - the index of the element to get.
      Returns:
      the element at the given index.
    • indexOf

      public int indexOf(Object object)
      Returns the index in this list of the first occurrence of the specified element, or -1 if the list does not contain the element.
      Specified by:
      indexOf in interface List<E>
      Overrides:
      indexOf in class AbstractList<E>
      Parameters:
      object - the element to search for.
      Returns:
      the index of the first occurrence of the given object, or -1.
    • lastIndexOf

      public int lastIndexOf(Object object)
      Returns the index in this list of the last occurrence of the specified element, or -1 if the list does not contain the element.
      Specified by:
      lastIndexOf in interface List<E>
      Overrides:
      lastIndexOf in class AbstractList<E>
      Parameters:
      object - the element to search for.
      Returns:
      the index of the last occurrence of the given object, or -1.
    • contains

      public boolean contains(Object object)
      Returns true if this list contains the specified element.
      Specified by:
      contains in interface Collection<E>
      Specified by:
      contains in interface List<E>
      Overrides:
      contains in class AbstractCollection<E>
      Parameters:
      object - the element to check for existence.
      Returns:
      true if this collection contains the given element.
    • subList

      public UnmodifiableArrayList<E> subList(int lower, int upper) throws IndexOutOfBoundsException
      Returns a view of the portion of this list between the specified lower, inclusive, and upper, exclusive.
      Specified by:
      subList in interface List<E>
      Overrides:
      subList in class AbstractList<E>
      Parameters:
      lower - low endpoint (inclusive) of the sublist.
      upper - high endpoint (exclusive) of the sublist.
      Returns:
      a view of the specified range within this list.
      Throws:
      IndexOutOfBoundsException - if the lower or upper value are out of bounds.
      See Also:
    • toArray

      public E[] toArray()
      Returns a copy of the backing array. Note that the array type is E[] rather than Object[]. This is not what ArrayList does, but is not forbidden by List.toArray() javadoc neither.
      Specified by:
      toArray in interface Collection<E>
      Specified by:
      toArray in interface List<E>
      Overrides:
      toArray in class AbstractCollection<E>
      Returns:
      a copy of the wrapped array.
    • toArray

      public <T> T[] toArray(T[] dest)
      Copies the backing array in the given one if the list fits in the given array. If the list does not fit in the given array, returns the collection in a new array.
      Specified by:
      toArray in interface Collection<E>
      Specified by:
      toArray in interface List<E>
      Overrides:
      toArray in class AbstractCollection<E>
      Type Parameters:
      T - the type of array element.
      Parameters:
      dest - the array where to copy the elements if the list can fits in the array.
      Returns:
      the given array, or a newly created array if this list is larger than the given array.
    • equals

      public boolean equals(Object object)
      Compares this list with the given object for equality.
      Specified by:
      equals in interface Collection<E>
      Specified by:
      equals in interface List<E>
      Overrides:
      equals in class AbstractList<E>
      Parameters:
      object - the object to compare with this list.
      Returns:
      true if the given object is equal to this list.