RegularImmutableList.java revision 0888a09821a98ac0680fad765217302858e70fa4
1/*
2 * Copyright (C) 2009 The Guava Authors
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.google.common.collect;
18
19import com.google.common.annotations.GwtCompatible;
20import com.google.common.base.Preconditions;
21
22import javax.annotation.Nullable;
23
24/**
25 * Implementation of {@link ImmutableList} with one or more elements.
26 *
27 * @author Kevin Bourrillion
28 */
29@GwtCompatible(serializable = true, emulated = true)
30@SuppressWarnings("serial") // uses writeReplace(), not default serialization
31class RegularImmutableList<E> extends ImmutableList<E> {
32  private final transient int offset;
33  private final transient int size;
34  private final transient Object[] array;
35
36  RegularImmutableList(Object[] array, int offset, int size) {
37    this.offset = offset;
38    this.size = size;
39    this.array = array;
40  }
41
42  RegularImmutableList(Object[] array) {
43    this(array, 0, array.length);
44  }
45
46  @Override
47  public int size() {
48    return size;
49  }
50
51  @Override boolean isPartialView() {
52    return size != array.length;
53  }
54
55  @Override
56  int copyIntoArray(Object[] dst, int dstOff) {
57    System.arraycopy(array, offset, dst, dstOff, size);
58    return dstOff + size;
59  }
60
61  // The fake cast to E is safe because the creation methods only allow E's
62  @Override
63  @SuppressWarnings("unchecked")
64  public E get(int index) {
65    Preconditions.checkElementIndex(index, size);
66    return (E) array[index + offset];
67  }
68
69  @Override
70  public int indexOf(@Nullable Object object) {
71    if (object == null) {
72      return -1;
73    }
74    for (int i = 0; i < size; i++) {
75      if (array[offset + i].equals(object)) {
76        return i;
77      }
78    }
79    return -1;
80  }
81
82  @Override
83  public int lastIndexOf(@Nullable Object object) {
84    if (object == null) {
85      return -1;
86    }
87    for (int i = size - 1; i >= 0; i--) {
88      if (array[offset + i].equals(object)) {
89        return i;
90      }
91    }
92    return -1;
93  }
94
95  @Override
96  ImmutableList<E> subListUnchecked(int fromIndex, int toIndex) {
97    return new RegularImmutableList<E>(
98        array, offset + fromIndex, toIndex - fromIndex);
99  }
100
101  @SuppressWarnings("unchecked")
102  @Override
103  public UnmodifiableListIterator<E> listIterator(int index) {
104    // for performance
105    // The fake cast to E is safe because the creation methods only allow E's
106    return (UnmodifiableListIterator<E>)
107        Iterators.forArray(array, offset, size, index);
108  }
109
110  // TODO(user): benchmark optimizations for equals() and see if they're worthwhile
111}
112