View Javadoc
1   /*
2   	Copyright (c) 2009 Olivier Chafik, All Rights Reserved
3   	
4   	This file is part of JNAerator (http://jnaerator.googlecode.com/).
5   	
6   	JNAerator is free software: you can redistribute it and/or modify
7   	it under the terms of the GNU General Public License as published by
8   	the Free Software Foundation, either version 3 of the License, or
9   	(at your option) any later version.
10  	
11  	JNAerator is distributed in the hope that it will be useful,
12  	but WITHOUT ANY WARRANTY; without even the implied warranty of
13  	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  	GNU General Public License for more details.
15  	
16  	You should have received a copy of the GNU General Public License
17  	along with JNAerator.  If not, see <http://www.gnu.org/licenses/>.
18  */
19  package com.ochafik.util;
20  import java.lang.reflect.Array;
21  import java.util.ArrayList;
22  import java.util.Arrays;
23  import java.util.Collection;
24  import java.util.Iterator;
25  import java.util.LinkedList;
26  import java.util.Vector;
27  
28  /*
29   * This is a Collection that gathers the content of several collections, without the need to create
30   *  a big structure and add them all to it. It is space and speed efficient (except for containsAll(Collection)),
31   *  however it does not implement add(U) and addAll(Collection<U>) optional methods. 
32   *  
33   * It should be use in cases where you want to iterate through several collections as through one.
34   */
35  public class CompoundCollection<U> implements Collection<U> {
36  	Collection<Collection<? extends U> > collections;
37  	public CompoundCollection() {
38  		collections=new LinkedList<Collection<? extends U> >();
39  	}
40  	public CompoundCollection(Collection<Collection<? extends U>> lists) {
41  		collections = new ArrayList<Collection<? extends U>>(lists);
42  	}
43  	public CompoundCollection(Collection<? extends U>... lists) {
44  		this(Arrays.asList(lists));
45  	}
46  	public void addComponent(Collection<U> col) {
47          collections.add(col);
48      }
49      public boolean removeComponent(Collection<U> col) {
50          return collections.remove(col);
51      }
52      public int size() {
53  		int s=0;
54  		for (Collection<? extends U> col : collections) {
55  			s+=col.size();
56  		}
57  		return s;
58  	}
59  	public void clearComponents() {
60  		collections.clear();
61  	}
62  	public void clear() {
63  		for (Collection<? extends U> col : collections) {
64  			col.clear();
65  		}
66  	}
67  	public boolean isEmpty() {
68  		for (Collection<? extends U> col : collections) {
69  			if (!col.isEmpty()) {
70  				return false; 
71  			}
72  		}
73  		return true;
74  	}
75  	public Object[] toArray() {
76  		int len=size();
77  		Object[] a=new Object[len];
78  		int i=0;
79  		for (U element : this) {
80  			a[i]=element;
81  		}
82  		return a;
83  	}
84      @SuppressWarnings("unchecked")
85      //@Deprecated
86      public <T> T[] toArray(T[] objects) {
87          int size=size();
88          Class<T> clazz=(Class<T>)objects.getClass().getComponentType();
89          T[] array=(T[])Array.newInstance(clazz,size);
90          int i=0;
91          for (Object element : this) {
92              array[i]=clazz.cast(element);
93          }
94          return array;
95  	}
96      @Deprecated
97  	public boolean add(U object) { 
98          throw new UnsupportedOperationException(); 
99      }    
100 	public boolean contains(Object object) {
101 		for (Collection<? extends U> col : collections) {
102 			if (col.contains(object)) {
103 				return true; 
104 			}
105 		}
106 		return false;
107 	}
108 	public boolean remove(Object object) {
109         boolean changed=false;
110 		for (Collection<? extends U> col : collections) {
111 			if (col.remove(object)) {
112                 changed=true;
113 				//return true; 
114 			}
115 		}
116         return changed;
117 		//return false;
118 	}
119     @Deprecated
120     public boolean addAll(Collection<? extends U> col) {
121         boolean changed=false;
122         for (U u : col) {
123             changed=add(u) || changed;
124         } 
125         return changed;
126 	}
127     public boolean containsAll(Collection<?> col) {
128         for (Object o : col) {
129             if (!contains(o)) {
130                 return false;
131             }
132         }
133         return true; 
134 	}
135     public boolean removeAll(Collection<?> col) {
136         boolean changed=false;
137         for (Object o : col) {
138             changed=remove(o) || changed;
139         } 
140         return changed;
141 	}
142     public boolean retainAll(Collection<?> col) {
143         boolean changed=false;
144         for (Iterator<U> it=iterator();it.hasNext();) {
145             if (!col.contains(it.next())) {
146                 it.remove();
147                 changed=true;
148             }
149         }
150         return changed; 
151 	}
152 	public Iterator<U> iterator() {
153 		//final Iterator firstIterator=first.iterator(),restIterator=rest.iterator();
154 		return new Iterator<U>() {
155 			Iterator<? extends Collection<? extends U>> collectionsIterator=collections.iterator();
156 			Iterator<? extends U> currentCollectionIterator=
157 				collectionsIterator.hasNext() ?
158 					collectionsIterator.next().iterator() :
159 					new Vector<U>(0).iterator();
160 			public boolean hasNext() {
161 				boolean collectionExhausted=false;
162 				do {
163 					collectionExhausted=true;
164 					if (currentCollectionIterator.hasNext()) {
165 						return true;
166 					} else if (collectionsIterator.hasNext()) {
167 						currentCollectionIterator=collectionsIterator.next().iterator();
168 						collectionExhausted=false;
169 					} 
170 				} while (!collectionExhausted);
171 				return false;
172 			}
173 			public U next() {
174 				boolean collectionExhausted=false;
175 				do {
176 					collectionExhausted=true;
177 					if (currentCollectionIterator.hasNext()) {
178 						return currentCollectionIterator.next();
179 					} else {
180 						currentCollectionIterator=collectionsIterator.next().iterator();
181 						collectionExhausted=false;
182 					}
183 				} while (!collectionExhausted);
184 				return null;
185 			}
186 			public void remove() {
187 				currentCollectionIterator.remove();
188 			}    
189 		};
190 	}
191 }