View Javadoc

    1   /* SubList
    2    *
    3    * $Id: SubList.java 4648 2006-09-25 16:25:53Z paul_jack $
    4    * Created on September 23, 2006
    5    *
    6    * Copyright (C) 2006 Internet Archive.
    7    *
    8    * This file is part of the Heritrix web crawler (crawler.archive.org).
    9    *
    10   * Heritrix is free software; you can redistribute it and/or modify
    11   * it under the terms of the GNU Lesser Public License as published by
    12   * the Free Software Foundation; either version 2.1 of the License, or
    13   * any later version.
    14   *
    15   * Heritrix is distributed in the hope that it will be useful,
    16   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    17   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    18   * GNU Lesser Public License for more details.
    19   *
    20   * You should have received a copy of the GNU Lesser Public License
    21   * along with Heritrix; if not, write to the Free Software
    22   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    23   */
    24  package org.archive.util;
    25
    26
    27  import java.io.Serializable;
    28  import java.util.AbstractList;
    29  import java.util.List;
    30
    31
    32  /***
    33   * Universal sublist implementation.  Instances of this class are
    34   * appropriate to return from {@link List#subList(int, int)}
    35   * implementations.
    36   *
    37   * <p>This implementation is efficient if the super list is random-access.
    38   * LinkedList-style super lists should subclass this and provide a custom
    39   * iterator.
    40   *
    41   * @author pjack
    42   * @param <E>  the element type of the list
    43   */
    44  public class SubList<E> extends AbstractList<E> implements Serializable {
    45
    46      private static final long serialVersionUID = 1L;
    47
    48      /***
    49       * The list that created this SubList.
    50       */
    51      final private List<E> delegate;
    52
    53      /***
    54       * The starting index of the SubList, inclusive.
    55       */
    56      private int start;
    57
    58      /***
    59       * The ending index of the SubList, exclusive.
    60       */
    61      private int end;
    62
    63
    64      /***
    65       * Constructor.
    66       *
    67       * @param delegate  the list that create this SubList
    68       * @param start   the starting index of the sublist, inclusive
    69       * @param end  the ending index of the sublist, exclusive
    70       * @throws IndexOutOfBoundsException   if start or end are outside the
    71       *   bounds of the list
    72       * @throws IllegalArgumentException  if end is less than start
    73       */
    74      public SubList(List<E> delegate, int start, int end) {
    75          if ((start < 0) || (start > delegate.size())) {
    76              throw new IndexOutOfBoundsException();
    77          }
    78          if ((end < 0) || (end > delegate.size())) {
    79              throw new IndexOutOfBoundsException();
    80          }
    81          if (end < start) {
    82              throw new IllegalArgumentException();
    83          }
    84          this.delegate = delegate;
    85          this.start = start;
    86          this.end = end;
    87      }
    88
    89      /***
    90       * Ensures that the given index is strictly within the bounds of this
    91       * SubList.
    92       *
    93       * @param index  the index to check
    94       * @throws  IndexOutOfBoundsException  if the index is out of bounds
    95       */
    96      private void ensureInside(int index) {
    97          if ((index < 0) || (index >= end - start)) {
    98              throw new IndexOutOfBoundsException();
    99          }
    100     }
    101
    102     /***
    103      * Ensures that the given index is either within bounds or on the border
    104      * of this SubList.  In other words, this method allows the given index
    105      * to be equal to {@link #size()}.
    106      *
    107      * @param index  the index to check
    108      * @throws  IndexOutOfBoundsException  if the index is out of bounds
    109      */
    110     private void ensureBorder(int index) {
    111         if ((index < 0) || (index > end - start)) {
    112             throw new IndexOutOfBoundsException();
    113         }
    114     }
    115
    116
    117     @Override
    118     public E get(int index) {
    119         ensureInside(index);
    120         return delegate.get(start + index);
    121     }
    122
    123
    124     @Override
    125     public int size() {
    126         return end - start;
    127     }
    128
    129
    130     @Override
    131     public E set(int index, E value) {
    132         ensureInside(index);
    133         return delegate.set(start + index, value);
    134     }
    135
    136
    137     @Override
    138     public void add(int index, E value) {
    139         ensureBorder(index);
    140         delegate.add(start + index, value);
    141         end++;
    142     }
    143
    144
    145     @Override
    146     public E remove(int index) {
    147         ensureInside(index);
    148         return delegate.remove(start + index);
    149     }
    150 }