001/******************************************************************************* 002 * Copyright (c) 2014 Opt4J 003 * 004 * Permission is hereby granted, free of charge, to any person obtaining a copy 005 * of this software and associated documentation files (the "Software"), to deal 006 * in the Software without restriction, including without limitation the rights 007 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 008 * copies of the Software, and to permit persons to whom the Software is 009 * furnished to do so, subject to the following conditions: 010 * 011 * The above copyright notice and this permission notice shall be included in 012 * all copies or substantial portions of the Software. 013 * 014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 015 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 016 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 017 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 018 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 019 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 020 * SOFTWARE. 021 *******************************************************************************/ 022 023package org.opt4j.core; 024 025import java.util.Arrays; 026import java.util.Collection; 027import java.util.Iterator; 028import java.util.LinkedHashSet; 029import java.util.Set; 030import java.util.concurrent.CopyOnWriteArraySet; 031 032/** 033 * The {@link IndividualSet} is a {@link Set} of {@link Individual}s. It allows 034 * to add and remove listeners, see {@link IndividualSetListener}. 035 * 036 * @see org.opt4j.core.optimizer.Archive 037 * @see org.opt4j.core.optimizer.Population 038 * @author lukasiewycz 039 * 040 */ 041public class IndividualSet implements Set<Individual> { 042 043 protected final Set<Individual> individuals = new LinkedHashSet<>(); 044 045 protected final Set<IndividualSetListener> listeners = new CopyOnWriteArraySet<>(); 046 047 /* 048 * (non-Javadoc) 049 * 050 * @see java.util.Collection#add(java.lang.Object) 051 */ 052 @Override 053 public boolean add(Individual individual) { 054 boolean b = false; 055 if (!individuals.contains(individual)) { 056 b = individuals.add(individual); 057 } 058 if (b) { 059 for (IndividualSetListener listener : listeners) { 060 listener.individualAdded(this, individual); 061 } 062 } 063 return b; 064 } 065 066 /* 067 * (non-Javadoc) 068 * 069 * @see java.util.Collection#iterator() 070 */ 071 @Override 072 public Iterator<Individual> iterator() { 073 final Iterator<Individual> iterator = individuals.iterator(); 074 075 return new Iterator<Individual>() { 076 077 Individual current = null; 078 079 @Override 080 public boolean hasNext() { 081 return iterator.hasNext(); 082 } 083 084 @Override 085 public Individual next() { 086 current = iterator.next(); 087 return current; 088 } 089 090 @Override 091 public void remove() { 092 iterator.remove(); 093 if (current != null) { 094 for (IndividualSetListener listener : listeners) { 095 listener.individualRemoved(IndividualSet.this, current); 096 } 097 } 098 } 099 }; 100 101 } 102 103 /* 104 * (non-Javadoc) 105 * 106 * @see java.util.Collection#size() 107 */ 108 @Override 109 public int size() { 110 return individuals.size(); 111 } 112 113 /** 114 * Adds a listener. 115 * 116 * @see #removeListener 117 * @param listener 118 * the added listener 119 */ 120 public void addListener(IndividualSetListener listener) { 121 listeners.add(listener); 122 } 123 124 /** 125 * Removes a listener. 126 * 127 * @see #addListener 128 * @param listener 129 * the removed listener 130 */ 131 public void removeListener(IndividualSetListener listener) { 132 listeners.remove(listener); 133 } 134 135 /* 136 * (non-Javadoc) 137 * 138 * @see java.util.Collection#clear() 139 */ 140 @Override 141 public void clear() { 142 Iterator<Individual> it = iterator(); 143 while (it.hasNext()) { 144 it.next(); 145 it.remove(); 146 } 147 } 148 149 /* 150 * (non-Javadoc) 151 * 152 * @see java.util.Collection#addAll(java.util.Collection) 153 */ 154 @Override 155 public boolean addAll(Collection<? extends Individual> c) { 156 boolean res = false; 157 for (Individual individual : c) { 158 res |= add(individual); 159 } 160 return res; 161 } 162 163 /** 164 * Add all {@link Individual}s. 165 * 166 * @param c 167 * the individuals to be added 168 * @return true if at least one individual was added 169 */ 170 public boolean addAll(Individual... c) { 171 return addAll(Arrays.asList(c)); 172 } 173 174 /* 175 * (non-Javadoc) 176 * 177 * @see java.util.Collection#contains(java.lang.Object) 178 */ 179 @Override 180 public boolean contains(Object o) { 181 return individuals.contains(o); 182 } 183 184 /* 185 * (non-Javadoc) 186 * 187 * @see java.util.Collection#containsAll(java.util.Collection) 188 */ 189 @Override 190 public boolean containsAll(Collection<?> c) { 191 return individuals.containsAll(c); 192 } 193 194 /* 195 * (non-Javadoc) 196 * 197 * @see java.util.Collection#isEmpty() 198 */ 199 @Override 200 public boolean isEmpty() { 201 return individuals.isEmpty(); 202 } 203 204 /* 205 * (non-Javadoc) 206 * 207 * @see java.util.Collection#remove(java.lang.Object) 208 */ 209 @Override 210 public boolean remove(Object o) { 211 boolean value = individuals.remove(o); 212 if (value) { 213 for (IndividualSetListener listener : listeners) { 214 listener.individualRemoved(this, (Individual) o); 215 } 216 } 217 return value; 218 } 219 220 /* 221 * (non-Javadoc) 222 * 223 * @see java.util.Collection#removeAll(java.util.Collection) 224 */ 225 @Override 226 public boolean removeAll(Collection<?> c) { 227 boolean res = false; 228 Iterator<Individual> it = iterator(); 229 while (it.hasNext()) { 230 if (c.contains(it.next())) { 231 it.remove(); 232 res = true; 233 } 234 } 235 return res; 236 } 237 238 /* 239 * (non-Javadoc) 240 * 241 * @see java.util.Collection#retainAll(java.util.Collection) 242 */ 243 @Override 244 public boolean retainAll(Collection<?> c) { 245 boolean res = false; 246 Iterator<Individual> it = iterator(); 247 while (it.hasNext()) { 248 if (!c.contains(it.next())) { 249 it.remove(); 250 res = true; 251 } 252 } 253 return res; 254 } 255 256 /* 257 * (non-Javadoc) 258 * 259 * @see java.util.Collection#toArray() 260 */ 261 @Override 262 public Object[] toArray() { 263 return individuals.toArray(); 264 } 265 266 /* 267 * (non-Javadoc) 268 * 269 * @see java.util.Collection#toArray(T[]) 270 */ 271 @Override 272 public <T> T[] toArray(T[] a) { 273 return individuals.toArray(a); 274 } 275 276}