Overview Package Class Use Source Tree Index Deprecated About
GNU Classpath (0.95)
Frames | No Frames

Source for java.util.EnumMap

 1:  /* EnumMap.java - Map where keys are enum constants
 2:  Copyright (C) 2004, 2005 Free Software Foundation, Inc.
 3: 
 4: This file is part of GNU Classpath.
 5: 
 6: GNU Classpath 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 2, or (at your option)
 9: any later version.
 10: 
 11: GNU Classpath is distributed in the hope that it will be useful, but
 12: WITHOUT ANY WARRANTY; without even the implied warranty of
 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 14: General Public License for more details.
 15: 
 16: You should have received a copy of the GNU General Public License
 17: along with GNU Classpath; see the file COPYING. If not, write to the
 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 19: 02110-1301 USA.
 20: 
 21: Linking this library statically or dynamically with other modules is
 22: making a combined work based on this library. Thus, the terms and
 23: conditions of the GNU General Public License cover the whole
 24: combination.
 25: 
 26: As a special exception, the copyright holders of this library give you
 27: permission to link this library with independent modules to produce an
 28: executable, regardless of the license terms of these independent
 29: modules, and to copy and distribute the resulting executable under
 30: terms of your choice, provided that you also meet, for each linked
 31: independent module, the terms and conditions of the license of that
 32: module. An independent module is a module which is not derived from
 33: or based on this library. If you modify this library, you may extend
 34: this exception to your version of the library, but you are not
 35: obligated to do so. If you do not wish to do so, delete this
 36: exception statement from your version. */
 37: 
 38: 
 39:  package java.util;
 40: 
 41:  import java.io.Serializable;
 42: 
 43:  /** 
 44:  * @author Tom Tromey (tromey@redhat.com)
 45:  * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 46:  * @since 1.5 
 47:  */
 48: 
 49:  public class EnumMap<K extends Enum<K>, V>
 50:  extends AbstractMap<K, V>
 51:  implements Cloneable, Serializable
 52: {
 53:  private static final long serialVersionUID = 458661240069192865L;
 54: 
 55:  V[] store;
 56:  int cardinality;
 57:  Class<K> enumClass;
 58: 
 59:  /**
 60:  * The cache for {@link #entrySet()}.
 61:  */
 62:  transient Set<Map.Entry<K, V>> entries;
 63: 
 64:  static final Object emptySlot = new Object();
 65: 
 66:  public EnumMap(Class<K> keyType)
 67:  {
 68:  store = (V[]) new Object[keyType.getEnumConstants().length];
 69:  Arrays.fill(store, emptySlot);
 70:  cardinality = 0;
 71:  enumClass = keyType;
 72:  }
 73: 
 74:  public EnumMap(EnumMap<K, ? extends V> map)
 75:  {
 76:  store = (V[]) map.store.clone();
 77:  cardinality = map.cardinality;
 78:  enumClass = map.enumClass;
 79:  }
 80: 
 81:  public EnumMap(Map<K, ? extends V> map)
 82:  {
 83:  if (map instanceof EnumMap)
 84:  {
 85:  EnumMap<K, ? extends V> other = (EnumMap<K, ? extends V>) map;
 86:  store = (V[]) other.store.clone();
 87:  cardinality = other.cardinality;
 88:  enumClass = other.enumClass;
 89:  }
 90:  else
 91:  {
 92:  for (K key : map.keySet())
 93:  {
 94:  V value = map.get(key);
 95:  if (store == null)
 96:  {
 97:  enumClass = key.getDeclaringClass();
 98:  store = (V[]) new Object[enumClass.getEnumConstants().length];
 99:  }
 100:  int o = key.ordinal();
 101:  if (store[o] == emptySlot)
 102:  ++cardinality;
 103:  store[o] = value;
 104:  }
 105:  // There must be a single element.
 106:  if (store == null)
 107:  throw new IllegalArgumentException("no elements in map");
 108:  }
 109:  }
 110: 
 111:  public int size()
 112:  {
 113:  return cardinality;
 114:  }
 115: 
 116:  public boolean containsValue(Object value)
 117:  {
 118:  for (V i : store)
 119:  {
 120:  if (i != emptySlot && AbstractCollection.equals(i , value))
 121:  return true;
 122:  }
 123:  return false;
 124:  }
 125: 
 126:  public boolean containsKey(Object key)
 127:  {
 128:  if (! (key instanceof Enum))
 129:  return false;
 130:  Enum<K> e = (Enum<K>) key;
 131:  if (e.getDeclaringClass() != enumClass)
 132:  return false;
 133:  return store[e.ordinal()] != emptySlot;
 134:  }
 135: 
 136:  public V get(Object key)
 137:  {
 138:  if (! (key instanceof Enum))
 139:  return null;
 140:  Enum<K> e = (Enum<K>) key;
 141:  if (e.getDeclaringClass() != enumClass)
 142:  return null;
 143:  return store[e.ordinal()];
 144:  }
 145: 
 146:  public V put(K key, V value)
 147:  {
 148:  int o = key.ordinal();
 149:  V result;
 150:  if (store[o] == emptySlot)
 151:  {
 152:  result = null;
 153:  ++cardinality;
 154:  }
 155:  else
 156:  result = store[o];
 157:  store[o] = value;
 158:  return result;
 159:  }
 160: 
 161:  public V remove(Object key)
 162:  {
 163:  if (! (key instanceof Enum))
 164:  return null;
 165:  Enum<K> e = (Enum<K>) key;
 166:  if (e.getDeclaringClass() != enumClass)
 167:  return null;
 168:  V result = store[e.ordinal()];
 169:  if (result == emptySlot)
 170:  result = null;
 171:  else
 172:  --cardinality;
 173:  store[e.ordinal()] = (V) emptySlot;
 174:  return result;
 175:  }
 176: 
 177:  public void putAll(Map<? extends K, ? extends V> map)
 178:  {
 179:  for (K key : map.keySet())
 180:  {
 181:  V value = map.get(key);
 182: 
 183:  int o = key.ordinal();
 184:  if (store[o] == emptySlot)
 185:  ++cardinality;
 186:  store[o] = value;
 187:  }
 188:  }
 189: 
 190:  public void clear()
 191:  {
 192:  Arrays.fill(store, emptySlot);
 193:  cardinality = 0;
 194:  }
 195: 
 196:  public Set<K> keySet()
 197:  {
 198:  if (keys == null)
 199:  {
 200:  keys = new AbstractSet<K>()
 201:  {
 202:  public int size()
 203:  {
 204:  return cardinality;
 205:  }
 206: 
 207:  public Iterator<K> iterator()
 208:  {
 209:  return new Iterator<K>()
 210:  {
 211:  int count = 0;
 212:  int index = -1;
 213: 
 214:  public boolean hasNext()
 215:  {
 216:  return count < cardinality;
 217:  }
 218: 
 219:  public K next()
 220:  {
 221:  ++count;
 222:  for (++index; store[index] == emptySlot; ++index)
 223:  ;
 224:  return enumClass.getEnumConstants()[index];
 225:  }
 226: 
 227:  public void remove()
 228:  {
 229:  --cardinality;
 230:  store[index] = (V) emptySlot;
 231:  }
 232:  };
 233:  }
 234: 
 235:  public void clear()
 236:  {
 237:  EnumMap.this.clear();
 238:  }
 239: 
 240:  public boolean contains(Object o)
 241:  {
 242:  return contains(o);
 243:  }
 244: 
 245:  public boolean remove(Object o)
 246:  {
 247:  return EnumMap.this.remove(o) != null;
 248:  }
 249:  };
 250:  }
 251:  return keys;
 252:  }
 253: 
 254:  public Collection<V> values()
 255:  {
 256:  if (values == null)
 257:  {
 258:  values = new AbstractCollection<V>()
 259:  {
 260:  public int size()
 261:  {
 262:  return cardinality;
 263:  }
 264: 
 265:  public Iterator<V> iterator()
 266:  {
 267:  return new Iterator<V>()
 268:  {
 269:  int count = 0;
 270:  int index = -1;
 271: 
 272:  public boolean hasNext()
 273:  {
 274:  return count < cardinality;
 275:  }
 276: 
 277:  public V next()
 278:  {
 279:  ++count;
 280:  for (++index; store[index] == emptySlot; ++index)
 281:  ;
 282:  return store[index];
 283:  }
 284: 
 285:  public void remove()
 286:  {
 287:  --cardinality;
 288:  store[index] = (V) emptySlot;
 289:  }
 290:  };
 291:  }
 292: 
 293:  public void clear()
 294:  {
 295:  EnumMap.this.clear();
 296:  }
 297:  };
 298:  }
 299:  return values;
 300:  }
 301: 
 302:  public Set<Map.Entry<K, V>> entrySet()
 303:  {
 304:  if (entries == null)
 305:  {
 306:  entries = new AbstractSet<Map.Entry<K, V>>()
 307:  {
 308:  public int size()
 309:  {
 310:  return cardinality;
 311:  }
 312: 
 313:  public Iterator<Map.Entry<K, V>> iterator()
 314:  {
 315:  return new Iterator<Map.Entry<K, V>>()
 316:  {
 317:  int count = 0;
 318:  int index = -1;
 319: 
 320:  public boolean hasNext()
 321:  {
 322:  return count < cardinality;
 323:  }
 324: 
 325:  public Map.Entry<K,V> next()
 326:  {
 327:  ++count;
 328:  for (++index; store[index] == emptySlot; ++index)
 329:  ;
 330:  // FIXME: we could just return something that
 331:  // only knows the index. That would be cleaner.
 332:  return new AbstractMap.SimpleEntry<K, V>(enumClass.getEnumConstants()[index],
 333:  store[index])
 334:  {
 335:  public V setValue(V newVal)
 336:  {
 337:  value = newVal;
 338:  return put(key, newVal);
 339:  }
 340:  };
 341:  }
 342: 
 343:  public void remove()
 344:  {
 345:  --cardinality;
 346:  store[index] = (V) emptySlot;
 347:  }
 348:  };
 349:  }
 350: 
 351:  public void clear()
 352:  {
 353:  EnumMap.this.clear();
 354:  }
 355: 
 356:  public boolean contains(Object o)
 357:  {
 358:  if (! (o instanceof Map.Entry))
 359:  return false;
 360:  Map.Entry<K, V> other = (Map.Entry<K, V>) o;
 361:  return (containsKey(other.getKey())
 362:  && AbstractCollection.equals(get(other.getKey()),
 363:  other.getValue()));
 364:  }
 365: 
 366:  public boolean remove(Object o)
 367:  {
 368:  if (! (o instanceof Map.Entry))
 369:  return false;
 370:  Map.Entry<K, V> other = (Map.Entry<K, V>) o;
 371:  return EnumMap.this.remove(other.getKey()) != null;
 372:  }
 373:  };
 374:  }
 375:  return entries;
 376:  }
 377: 
 378:  public boolean equals(Object o)
 379:  {
 380:  if (! (o instanceof EnumMap))
 381:  return false;
 382:  EnumMap<K, V> other = (EnumMap<K, V>) o;
 383:  if (other.enumClass != enumClass || other.cardinality != cardinality)
 384:  return false;
 385:  return Arrays.equals(store, other.store);
 386:  }
 387: 
 388:  public EnumMap<K, V> clone()
 389:  {
 390:  /* This constructor provides this functionality */
 391:  return new EnumMap(this);
 392:  }
 393: 
 394: }
Overview Package Class Use Source Tree Index Deprecated About
GNU Classpath (0.95)

AltStyle によって変換されたページ (->オリジナル) /