001/** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.xbean.finder.util; 018 019import java.lang.reflect.Array; 020import java.util.Collection; 021import java.util.Iterator; 022import java.util.List; 023import java.util.ListIterator; 024import java.util.NoSuchElementException; 025 026public class SingleLinkedList<E> implements List<E> { 027 028 private Entry<E> entry; 029 private int size = 0; 030 031 private class Entry<E> { 032 033 private E value; 034 private Entry next; 035 036 private Entry(E value, Entry next) { 037 this.value = value; 038 this.next = next; 039 } 040 } 041 042 043 public int size() { 044 return size; 045 } 046 047 public boolean isEmpty() { 048 return size() == 0; 049 } 050 051 public boolean contains(Object o) { 052 if (o == null) { 053 for (E e : this) { 054 if (null == e) return true; 055 } 056 } else { 057 for (E e : this) { 058 if (o.equals(e)) return true; 059 } 060 } 061 062 return false; 063 } 064 065 public Iterator<E> iterator() { 066 return values(); 067 } 068 069 public Object[] toArray() { 070 final Object[] array = new Object[size]; 071 return toArray(array); 072 } 073 074 public <T> T[] toArray(T[] a) { 075 if (a.length < size) a = (T[]) Array.newInstance(a.getClass().getComponentType(), size); 076 077 Object[] array = a; 078 int i = 0; 079 080 for (E e : this) { 081 array[i++] = e; 082 } 083 084 return (T[]) array; 085 } 086 087 public boolean add(E e) { 088 this.entry = new Entry(e, this.entry); 089 size++; 090 return true; 091 } 092 093 public boolean remove(Object o) { 094 throw new UnsupportedOperationException("remove"); 095 } 096 097 public boolean containsAll(Collection<?> c) { 098 throw new UnsupportedOperationException("containsAll"); 099 } 100 101 public boolean addAll(Collection<? extends E> c) { 102 throw new UnsupportedOperationException("addAll"); 103 } 104 105 public boolean addAll(int index, Collection<? extends E> c) { 106 throw new UnsupportedOperationException("addAll"); 107 } 108 109 public boolean removeAll(Collection<?> c) { 110 throw new UnsupportedOperationException("removeAll"); 111 } 112 113 public boolean retainAll(Collection<?> c) { 114 throw new UnsupportedOperationException("retainAll"); 115 } 116 117 public void clear() { 118 this.entry = null; 119 this.size = 0; 120 } 121 122 public E get(int index) { 123 bounds(index); 124 int i = size; 125 for (E e : this) { 126 if (--i == index) return e; 127 } 128 129 throw new IllegalStateException("statement should not be reachable"); 130 } 131 132 public E set(int index, E element) { 133 bounds(index); 134 int i = size; 135 136 for (Entry<E> entry : entries()) { 137 if (--i == index) { 138 final E old = entry.value; 139 entry.value = element; 140 return old; 141 } 142 } 143 144 throw new IllegalStateException("statement should not be reachable"); 145 } 146 147 public void add(int index, E element) { 148 throw new UnsupportedOperationException("add"); 149 } 150 151 public E remove(int index) { 152 throw new UnsupportedOperationException("remove"); 153 } 154 155 public int indexOf(Object o) { 156 throw new UnsupportedOperationException("indexOf"); 157 } 158 159 public int lastIndexOf(Object o) { 160 throw new UnsupportedOperationException("lastIndexOf"); 161 } 162 163 public ListIterator<E> listIterator() { 164 throw new UnsupportedOperationException("listIterator"); 165 } 166 167 public ListIterator<E> listIterator(int index) { 168 throw new UnsupportedOperationException("listIterator"); 169 } 170 171 public List<E> subList(int fromIndex, int toIndex) { 172 throw new UnsupportedOperationException("subList"); 173 } 174 175 private void bounds(int index) { 176 if (index >= size) throw new IndexOutOfBoundsException(index + " [size " + size + "]"); 177 if (index < 0) throw new IndexOutOfBoundsException(index + " [size " + size + "]"); 178 } 179 180 181 private Iterator<E> values() { 182 return new Values<E>(this.entry); 183 } 184 185 private Entries entries() { 186 return new Entries(this.entry); 187 } 188 189 190 private class Values<E> implements Iterator<E> { 191 192 private Entry<E> current; 193 194 private Values(Entry<E> current) { 195 this.current = current; 196 } 197 198 public boolean hasNext() { 199 return current != null; 200 } 201 202 public E next() { 203 if (current == null) throw new NoSuchElementException(); 204 205 final E v = current.value; 206 207 this.current = current.next; 208 209 return v; 210 } 211 212 public void remove() { 213 throw new UnsupportedOperationException("remove"); 214 } 215 } 216 217 private class Entries implements Iterator<Entry<E>>, Iterable<Entry<E>> { 218 private Entry<E> current; 219 220 private Entries(Entry<E> current) { 221 this.current = current; 222 } 223 224 public Iterator<Entry<E>> iterator() { 225 return this; 226 } 227 228 public boolean hasNext() { 229 return current != null; 230 } 231 232 public Entry<E> next() { 233 if (current == null) throw new NoSuchElementException(); 234 235 final Entry<E> value = this.current; 236 237 this.current = current.next; 238 239 return value; 240 } 241 242 public void remove() { 243 throw new UnsupportedOperationException("remove"); 244 } 245 } 246}