KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > db4o > foundation > Collection4


1 /* Copyright (C) 2004 - 2006 db4objects Inc. http://www.db4o.com
2
3 This file is part of the db4o open source object database.
4
5 db4o is free software; you can redistribute it and/or modify it under
6 the terms of version 2 of the GNU General Public License as published
7 by the Free Software Foundation and as clarified by db4objects' GPL
8 interpretation policy, available at
9 http://www.db4o.com/about/company/legalpolicies/gplinterpretation/
10 Alternatively you can write to db4objects, Inc., 1900 S Norfolk Street,
11 Suite 350, San Mateo, CA 94403, USA.
12
13 db4o is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License along
19 with this program; if not, write to the Free Software Foundation, Inc.,
20 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */

21 package com.db4o.foundation;
22
23 import com.db4o.types.Unversioned;
24
25 /**
26  * Fast linked list for all usecases.
27  *
28  * @exclude
29  */

30 public class Collection4 implements Iterable4, DeepClone, Unversioned {
31     
32     // FIELDS ARE PUBLIC SO THEY CAN BE REFLECTED ON IN JDKs <= 1.1
33

34     /** first element of the linked list */
35     public List4 _first;
36     
37     public List4 _last;
38
39     /** number of elements collected */
40     public int _size;
41
42     public int _version;
43     
44     private static final Object JavaDoc NOT_FOUND = new Object JavaDoc();
45
46     public Collection4() {
47     }
48
49     public Collection4(Iterable4 other) {
50         addAll(other);
51     }
52     
53     public Collection4(Iterator4 iterator) {
54         addAll(iterator);
55     }
56
57     public Object JavaDoc singleElement() {
58         if (size() != 1) {
59             throw new IllegalStateException JavaDoc();
60         }
61         return _first._element;
62     }
63
64     /**
65      * Adds an element to the end of this collection.
66      *
67      * @param element
68      */

69     public final void add(Object JavaDoc element) {
70         doAdd(element);
71         changed();
72     }
73     
74     public final void prepend(Object JavaDoc element) {
75         doPrepend(element);
76         changed();
77     }
78
79     private void doPrepend(Object JavaDoc element) {
80         if (_first == null) {
81             doAdd(element);
82         } else {
83             _first = new List4(_first, element);
84             _size++;
85         }
86     }
87
88     private void doAdd(Object JavaDoc element) {
89         if (_last == null) {
90             _first = new List4(element);
91             _last = _first;
92         } else {
93             _last._next = new List4(element);
94             _last = _last._next;
95         }
96         _size++;
97     }
98
99     public final void addAll(Object JavaDoc[] elements) {
100         assertNotNull(elements);
101         for (int i = 0; i < elements.length; i++) {
102             add(elements[i]);
103         }
104     }
105
106     public final void addAll(Iterable4 other) {
107         assertNotNull(other);
108         addAll(other.iterator());
109     }
110
111     public final void addAll(Iterator4 iterator) {
112         assertNotNull(iterator);
113         while (iterator.moveNext()) {
114             add(iterator.current());
115         }
116     }
117
118     public final void clear() {
119         _first = null;
120         _last = null;
121         _size = 0;
122         changed();
123     }
124
125     public final boolean contains(Object JavaDoc element) {
126         return getInternal(element) != NOT_FOUND;
127     }
128
129     public boolean containsAll(Iterator4 iter) {
130         assertNotNull(iter);
131         while (iter.moveNext()) {
132             if (!contains(iter.current())) {
133                 return false;
134             }
135         }
136         return true;
137     }
138
139     /**
140      * tests if the object is in the Collection. == comparison.
141      */

142     public final boolean containsByIdentity(Object JavaDoc element) {
143         Iterator4 i = internalIterator();
144         while (i.moveNext()) {
145             Object JavaDoc current = i.current();
146             if (current == element) {
147                 return true;
148             }
149         }
150         return false;
151     }
152
153     /**
154      * returns the first object found in the Collections that equals() the
155      * passed object
156      */

157     public final Object JavaDoc get(Object JavaDoc element) {
158         Object JavaDoc obj = getInternal(element);
159         if(obj == NOT_FOUND){
160             return null;
161         }
162         return obj;
163     }
164     
165     private final Object JavaDoc getInternal(Object JavaDoc element){
166         if (element == null) {
167             return containsNull() ? null : NOT_FOUND;
168         }
169         Iterator4 i = internalIterator();
170         while (i.moveNext()) {
171             Object JavaDoc current = i.current();
172             if (element.equals(current)) {
173                 return current;
174             }
175         }
176         return NOT_FOUND;
177     }
178     
179     private final boolean containsNull(){
180         return containsByIdentity(null);
181     }
182
183     public Object JavaDoc deepClone(Object JavaDoc newParent) {
184         Collection4 col = new Collection4();
185         Object JavaDoc element = null;
186         Iterator4 i = internalIterator();
187         while (i.moveNext()) {
188             element = i.current();
189             if (element instanceof DeepClone) {
190                 col.add(((DeepClone) element).deepClone(newParent));
191             } else {
192                 col.add(element);
193             }
194         }
195         return col;
196     }
197
198     /**
199      * makes sure the passed object is in the Collection. equals() comparison.
200      */

201     public final Object JavaDoc ensure(Object JavaDoc element) {
202         Object JavaDoc existing = getInternal(element);
203         if(existing == NOT_FOUND){
204             add(element);
205             return element;
206         }
207         return existing;
208     }
209
210     /**
211      * Iterates through the collection in reversed insertion order which happens
212      * to be the fastest.
213      *
214      * @return
215      */

216     public final Iterator4 iterator() {
217         return _first == null
218             ? Iterator4Impl.EMPTY
219             : new Collection4Iterator(this, _first);
220     }
221
222     /**
223      * removes an object from the Collection equals() comparison returns the
224      * removed object or null, if none found
225      */

226     public Object JavaDoc remove(Object JavaDoc a_object) {
227         List4 previous = null;
228         List4 current = _first;
229         while (current != null) {
230             if (current.holds(a_object)) {
231                 _size--;
232                 adjustOnRemoval(previous, current);
233                 changed();
234                 return current._element;
235             }
236             previous = current;
237             current = current._next;
238         }
239         return null;
240     }
241
242     private void adjustOnRemoval(List4 previous, List4 removed) {
243         if (removed == _first) {
244             _first = removed._next;
245         } else {
246             previous._next = removed._next;
247         }
248         if (removed == _last) {
249             _last = previous;
250         }
251     }
252
253     public final int size() {
254         return _size;
255     }
256     
257     public final boolean isEmpty() {
258         return _size == 0;
259     }
260
261     /**
262      * This is a non reflection implementation for more speed. In contrast to
263      * the JDK behaviour, the passed array has to be initialized to the right
264      * length.
265      */

266     public final Object JavaDoc[] toArray(Object JavaDoc[] a_array) {
267         int j = 0;
268         Iterator4 i = internalIterator();
269         while (i.moveNext()) {
270             a_array[j++] = i.current();
271         }
272         return a_array;
273     }
274
275     public final Object JavaDoc[] toArray() {
276         Object JavaDoc[] array = new Object JavaDoc[_size];
277         toArray(array);
278         return array;
279     }
280
281     public String JavaDoc toString() {
282         if (_size == 0) {
283             return "[]";
284         }
285         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
286         sb.append("[");
287         Iterator4 i = internalIterator();
288         i.moveNext();
289         sb.append(i.current());
290         while (i.moveNext()) {
291             sb.append(", ");
292             sb.append(i.current());
293         }
294         sb.append("]");
295         return sb.toString();
296     }
297
298     private void changed() {
299         ++_version;
300     }
301
302     int version() {
303         return _version;
304     }
305
306     private void assertNotNull(Object JavaDoc element) {
307         if (element == null) {
308             throw new ArgumentNullException();
309         }
310     }
311     
312     /**
313      * Leaner iterator for faster iteration (but unprotected against
314      * concurrent modifications).
315      */

316     private Iterator4 internalIterator() {
317         return new Iterator4Impl(_first);
318     }
319 }
Popular Tags