AbstractSet.java revision 3819a76e7c1f49253f0e077bd497f149340c02b8
1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18package java.util;
19
20/**
21 * An AbstractSet is an abstract implementation of the Set interface. This
22 * implementation does not support adding. A subclass must implement the
23 * abstract methods iterator() and size().
24 *
25 * @since 1.2
26 */
27public abstract class AbstractSet<E> extends AbstractCollection<E> implements
28        Set<E> {
29
30    /**
31     * Constructs a new instance of this AbstractSet.
32     */
33    protected AbstractSet() {
34        super();
35    }
36
37    /**
38     * Compares the specified object to this Set and returns true if they are
39     * equal. The object must be an instance of Set and contain the same
40     * objects.
41     *
42     * @param object
43     *            the object to compare with this set.
44     * @return {@code true} if the specified object is equal to this set,
45     *         {@code false} otherwise
46     * @see #hashCode
47     */
48    @Override
49    public boolean equals(Object object) {
50        if (this == object) {
51            return true;
52        }
53        if (object instanceof Set) {
54            Set<?> s = (Set<?>) object;
55
56            try {
57                return size() == s.size() && containsAll(s);
58            } catch (ClassCastException cce) {
59                return false;
60            }
61        }
62        return false;
63    }
64
65    /**
66     * Returns the hash code for this set. Two set which are equal must return
67     * the same value. This implementation calculates the hash code by adding
68     * each element's hash code.
69     *
70     * @return the hash code of this set.
71     * @see #equals
72     */
73    @Override
74    public int hashCode() {
75        int result = 0;
76        Iterator<?> it = iterator();
77        while (it.hasNext()) {
78            Object next = it.next();
79            result += next == null ? 0 : next.hashCode();
80        }
81        return result;
82    }
83
84    /**
85     * Removes all occurrences in this collection which are contained in the
86     * specified collection.
87     *
88     * @param collection
89     *            the collection of objects to remove.
90     * @return {@code true} if this collection was modified, {@code false}
91     *         otherwise.
92     * @throws UnsupportedOperationException
93     *                if removing from this collection is not supported.
94     */
95    @Override
96    public boolean removeAll(Collection<?> collection) {
97        boolean result = false;
98        if (size() <= collection.size()) {
99            Iterator<?> it = iterator();
100            while (it.hasNext()) {
101                if (collection.contains(it.next())) {
102                    it.remove();
103                    result = true;
104                }
105            }
106        } else {
107            Iterator<?> it = collection.iterator();
108            while (it.hasNext()) {
109                result = remove(it.next()) || result;
110            }
111        }
112        return result;
113    }
114}
115