1/*
2 * Copyright (C) 2007 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 static com.google.common.base.Preconditions.checkElementIndex;
20import static com.google.common.base.Preconditions.checkPositionIndex;
21import static com.google.common.base.Preconditions.checkPositionIndexes;
22
23import com.google.common.annotations.GwtCompatible;
24
25import java.util.Collection;
26import java.util.List;
27import java.util.NoSuchElementException;
28
29import javax.annotation.Nullable;
30
31/**
32 * An empty immutable list.
33 *
34 * @author Kevin Bourrillion
35 */
36@GwtCompatible(serializable = true, emulated = true)
37final class EmptyImmutableList extends ImmutableList<Object> {
38  static final EmptyImmutableList INSTANCE = new EmptyImmutableList();
39  static final UnmodifiableListIterator<Object> ITERATOR =
40      new UnmodifiableListIterator<Object>() {
41
42        @Override public boolean hasNext() {
43          return false;
44        }
45
46        @Override public boolean hasPrevious() {
47          return false;
48        }
49
50        @Override public Object next() {
51          throw new NoSuchElementException();
52        }
53
54        @Override public int nextIndex() {
55          return 0;
56        }
57
58        @Override public Object previous() {
59          throw new NoSuchElementException();
60        }
61
62        @Override public int previousIndex() {
63          return -1;
64        }
65      };
66
67  private EmptyImmutableList() {}
68
69  @Override
70  public int size() {
71    return 0;
72  }
73
74  @Override public boolean isEmpty() {
75    return true;
76  }
77
78  @Override boolean isPartialView() {
79    return false;
80  }
81
82  @Override public boolean contains(Object target) {
83    return false;
84  }
85
86  @Override public UnmodifiableIterator<Object> iterator() {
87    return Iterators.emptyIterator();
88  }
89
90  private static final Object[] EMPTY_ARRAY = new Object[0];
91
92  @Override public Object[] toArray() {
93    return EMPTY_ARRAY;
94  }
95
96  @Override public <T> T[] toArray(T[] a) {
97    if (a.length > 0) {
98      a[0] = null;
99    }
100    return a;
101  }
102
103  @Override
104  public Object get(int index) {
105    // guaranteed to fail, but at least we get a consistent message
106    checkElementIndex(index, 0);
107    throw new AssertionError("unreachable");
108  }
109
110  @Override public int indexOf(@Nullable Object target) {
111    return -1;
112  }
113
114  @Override public int lastIndexOf(@Nullable Object target) {
115    return -1;
116  }
117
118  @Override public ImmutableList<Object> subList(int fromIndex, int toIndex) {
119    checkPositionIndexes(fromIndex, toIndex, 0);
120    return this;
121  }
122
123  @Override public ImmutableList<Object> reverse() {
124    return this;
125  }
126
127  @Override public UnmodifiableListIterator<Object> listIterator(){
128    return ITERATOR;
129  }
130
131  @Override public UnmodifiableListIterator<Object> listIterator(int start) {
132    checkPositionIndex(start, 0);
133    return ITERATOR;
134  }
135
136  @Override public boolean containsAll(Collection<?> targets) {
137    return targets.isEmpty();
138  }
139
140  @Override public boolean equals(@Nullable Object object) {
141    if (object instanceof List) {
142      List<?> that = (List<?>) object;
143      return that.isEmpty();
144    }
145    return false;
146  }
147
148  @Override public int hashCode() {
149    return 1;
150  }
151
152  @Override public String toString() {
153    return "[]";
154  }
155
156  Object readResolve() {
157    return INSTANCE; // preserve singleton property
158  }
159
160  private static final long serialVersionUID = 0;
161}
162