001 /* 002 Copyright (c) 2009 Olivier Chafik, All Rights Reserved 003 004 This file is part of JNAerator (http://jnaerator.googlecode.com/). 005 006 JNAerator is free software: you can redistribute it and/or modify 007 it under the terms of the GNU General Public License as published by 008 the Free Software Foundation, either version 3 of the License, or 009 (at your option) any later version. 010 011 JNAerator is distributed in the hope that it will be useful, 012 but WITHOUT ANY WARRANTY; without even the implied warranty of 013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 014 GNU General Public License for more details. 015 016 You should have received a copy of the GNU General Public License 017 along with JNAerator. If not, see <http://www.gnu.org/licenses/>. 018 */ 019 package com.ochafik.util; 020 import java.lang.reflect.Array; 021 import java.util.ArrayList; 022 import java.util.Arrays; 023 import java.util.Collection; 024 import java.util.Iterator; 025 import java.util.LinkedList; 026 import java.util.Vector; 027 028 /* 029 * This is a Collection that gathers the content of several collections, without the need to create 030 * a big structure and add them all to it. It is space and speed efficient (except for containsAll(Collection)), 031 * however it does not implement add(U) and addAll(Collection<U>) optional methods. 032 * 033 * It should be use in cases where you want to iterate through several collections as through one. 034 */ 035 public class CompoundCollection<U> implements Collection<U> { 036 Collection<Collection<? extends U> > collections; 037 public CompoundCollection() { 038 collections=new LinkedList<Collection<? extends U> >(); 039 } 040 public CompoundCollection(Collection<Collection<? extends U>> lists) { 041 collections = new ArrayList<Collection<? extends U>>(lists); 042 } 043 public CompoundCollection(Collection<? extends U>... lists) { 044 this(Arrays.asList(lists)); 045 } 046 public void addComponent(Collection<U> col) { 047 collections.add(col); 048 } 049 public boolean removeComponent(Collection<U> col) { 050 return collections.remove(col); 051 } 052 public int size() { 053 int s=0; 054 for (Collection<? extends U> col : collections) { 055 s+=col.size(); 056 } 057 return s; 058 } 059 public void clearComponents() { 060 collections.clear(); 061 } 062 public void clear() { 063 for (Collection<? extends U> col : collections) { 064 col.clear(); 065 } 066 } 067 public boolean isEmpty() { 068 for (Collection<? extends U> col : collections) { 069 if (!col.isEmpty()) { 070 return false; 071 } 072 } 073 return true; 074 } 075 public Object[] toArray() { 076 int len=size(); 077 Object[] a=new Object[len]; 078 int i=0; 079 for (U element : this) { 080 a[i]=element; 081 } 082 return a; 083 } 084 @SuppressWarnings("unchecked") 085 //@Deprecated 086 public <T> T[] toArray(T[] objects) { 087 int size=size(); 088 Class<T> clazz=(Class<T>)objects.getClass().getComponentType(); 089 T[] array=(T[])Array.newInstance(clazz,size); 090 int i=0; 091 for (Object element : this) { 092 array[i]=clazz.cast(element); 093 } 094 return array; 095 } 096 @Deprecated 097 public boolean add(U object) { 098 throw new UnsupportedOperationException(); 099 } 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 }