001/**
002 *
003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved.
004 *
005 * This library is free software; you can redistribute it and/or
006 * modify it under the terms of the GNU Lesser General Public
007 * License as published by the Free Software Foundation; either 
008 * version 2.1 of the License, or (at your option) any later version.
009 * 
010 * This library is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013 * Lesser General Public License for more details.
014 * 
015 * You should have received a copy of the GNU Lesser General Public 
016 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
017 * 
018 **/
019/*
020 * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
021 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
022 *
023 *
024 *
025 *
026 *
027 *
028 *
029 *
030 *
031 *
032 *
033 *
034 *
035 *
036 *
037 *
038 *
039 *
040 *
041 *
042 */
043
044package lucee.commons.collection;
045
046import java.util.Collection;
047import java.util.Iterator;
048import java.util.Set;
049
050public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E> {
051    /**
052     * Sole constructor.  (For invocation by subclass constructors, typically
053     * implicit.)
054     */
055    protected AbstractSet() {
056    }
057
058    /**
059     * Compares the specified object with this set for equality.  Returns
060     * <tt>true</tt> if the given object is also a set, the two sets have
061     * the same size, and every member of the given set is contained in
062     * this set.  This ensures that the <tt>equals</tt> method works
063     * properly across different implementations of the <tt>Set</tt>
064     * interface.<p>
065     *
066     * This implementation first checks if the specified object is this
067     * set; if so it returns <tt>true</tt>.  Then, it checks if the
068     * specified object is a set whose size is identical to the size of
069     * this set; if not, it returns false.  If so, it returns
070     * <tt>containsAll((Collection) o)</tt>.
071     *
072     * @param o object to be compared for equality with this set
073     * @return <tt>true</tt> if the specified object is equal to this set
074     */
075    public boolean equals(Object o) {
076        if (o == this)
077            return true;
078
079        if (!(o instanceof Set))
080            return false;
081        Collection c = (Collection) o;
082        if (c.size() != size())
083            return false;
084        try {
085            return containsAll(c);
086        } catch (ClassCastException unused)   {
087            return false;
088        } catch (NullPointerException unused) {
089            return false;
090        }
091    }
092
093    @Override
094    public int hashCode() {
095        int h = 0;
096        Iterator<E> i = iterator();
097        while (i.hasNext()) {
098            E obj = i.next();
099            if (obj != null)
100                h += obj.hashCode();
101        }
102        return h;
103    }
104
105    @Override
106    public boolean removeAll(Collection<?> c) {
107        boolean modified = false;
108
109        if (size() > c.size()) {
110            for (Iterator<?> i = c.iterator(); i.hasNext(); )
111                modified |= remove(i.next());
112        } else {
113            for (Iterator<?> i = iterator(); i.hasNext(); ) {
114                if (c.contains(i.next())) {
115                    i.remove();
116                    modified = true;
117                }
118            }
119        }
120        return modified;
121    }
122
123}