ImmutableEnumSet.java revision 7dd252788645e940eada959bdde927426e2531c9
1/* 2 * Copyright (C) 2009 The Guava Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.google.common.collect; 18 19import com.google.common.annotations.GwtCompatible; 20 21import java.io.Serializable; 22import java.util.Collection; 23import java.util.EnumSet; 24 25/** 26 * Implementation of {@link ImmutableSet} backed by a non-empty {@link 27 * java.util.EnumSet}. 28 * 29 * @author Jared Levy 30 */ 31@GwtCompatible(serializable = true, emulated = true) 32@SuppressWarnings("serial") 33// we're overriding default serialization 34final class ImmutableEnumSet<E extends Enum<E>> extends ImmutableSet<E> { 35 static <E extends Enum<E>> ImmutableSet<E> asImmutable(EnumSet<E> set) { 36 switch (set.size()) { 37 case 0: 38 return ImmutableSet.of(); 39 case 1: 40 return ImmutableSet.of(Iterables.getOnlyElement(set)); 41 default: 42 return new ImmutableEnumSet<E>(set); 43 } 44 } 45 46 /* 47 * Notes on EnumSet and <E extends Enum<E>>: 48 * 49 * This class isn't an arbitrary ForwardingImmutableSet because we need to 50 * know that calling {@code clone()} during deserialization will return an 51 * object that no one else has a reference to, allowing us to guarantee 52 * immutability. Hence, we support only {@link EnumSet}. 53 */ 54 private final transient EnumSet<E> delegate; 55 56 private ImmutableEnumSet(EnumSet<E> delegate) { 57 this.delegate = delegate; 58 } 59 60 @Override 61 boolean isPartialView() { 62 return false; 63 } 64 65 @Override 66 public UnmodifiableIterator<E> iterator() { 67 return Iterators.unmodifiableIterator(delegate.iterator()); 68 } 69 70 public int size() { 71 return delegate.size(); 72 } 73 74 @Override 75 public boolean contains(Object object) { 76 return delegate.contains(object); 77 } 78 79 @Override 80 public boolean containsAll(Collection<?> collection) { 81 return delegate.containsAll(collection); 82 } 83 84 @Override 85 public boolean isEmpty() { 86 return delegate.isEmpty(); 87 } 88 89 @Override 90 public Object[] toArray() { 91 return delegate.toArray(); 92 } 93 94 @Override 95 public <T> T[] toArray(T[] array) { 96 return delegate.toArray(array); 97 } 98 99 @Override 100 public boolean equals(Object object) { 101 return object == this || delegate.equals(object); 102 } 103 104 private transient int hashCode; 105 106 @Override 107 public int hashCode() { 108 int result = hashCode; 109 return (result == 0) ? hashCode = delegate.hashCode() : result; 110 } 111 112 @Override 113 public String toString() { 114 return delegate.toString(); 115 } 116 117 // All callers of the constructor are restricted to <E extends Enum<E>>. 118 @Override 119 Object writeReplace() { 120 return new EnumSerializedForm<E>(delegate); 121 } 122 123 /* 124 * This class is used to serialize ImmutableEnumSet instances. 125 */ 126 private static class EnumSerializedForm<E extends Enum<E>> implements Serializable { 127 final EnumSet<E> delegate; 128 129 EnumSerializedForm(EnumSet<E> delegate) { 130 this.delegate = delegate; 131 } 132 133 Object readResolve() { 134 // EJ2 #76: Write readObject() methods defensively. 135 return new ImmutableEnumSet<E>(delegate.clone()); 136 } 137 138 private static final long serialVersionUID = 0; 139 } 140} 141