alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Commons Collections example source code file (DefaultMapBag.java)

This example Commons Collections source code file (DefaultMapBag.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Commons Collections tags/keywords

bag, bag, bagiterator, defaultmapbag, defaultmapbag, hashbag, integer, iterator, iterator, list, map, object, object, stringbuffer, util

The Commons Collections DefaultMapBag.java source code

/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.apache.commons.collections;

import java.util.ArrayList;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.collections.set.UnmodifiableSet;

/**
 * A skeletal implementation of the {@link Bag}
 * interface to minimize the effort required for target implementations.
 * Subclasses need only to call <code>setMap(Map) in their constructor 
 * (or invoke the Map constructor) specifying a map instance that will be used
 * to store the contents of the bag.
 * <p>
 * The map will be used to map bag elements to a number; the number represents
 * the number of occurrences of that element in the bag.
 *
 * @deprecated Moved to bag subpackage as AbstractMapBag. Due to be removed in v4.0.
 * @since Commons Collections 2.0
 * @version $Revision: 646777 $ $Date: 2008-04-10 13:33:15 +0100 (Thu, 10 Apr 2008) $
 * 
 * @author Chuck Burdick
 * @author Michael A. Smith
 * @author Stephen Colebourne
 * @author Janek Bogucki
 */
public abstract class DefaultMapBag implements Bag {
    private Map _map = null;
    private int _total = 0;
    private int _mods = 0;

    /**
     * No-argument constructor.  
     * Subclasses should invoke <code>setMap(Map) in
     * their constructors.
     */
    public DefaultMapBag() {
    }

    /**
     * Constructor that assigns the specified Map as the backing store.
     * The map must be empty.
     * 
     * @param map  the map to assign
     */
    protected DefaultMapBag(Map map) {
        setMap(map);
    }

    /**
     * Adds a new element to the bag by incrementing its count in the 
     * underlying map.
     *
     * @param object  the object to add
     * @return <code>true if the object was not already in the uniqueSet
     */
    public boolean add(Object object) {
        return add(object, 1);
    }

    /**
     * Adds a new element to the bag by incrementing its count in the map.
     *
     * @param object  the object to search for
     * @param nCopies  the number of copies to add
     * @return <code>true if the object was not already in the uniqueSet
     */
    public boolean add(Object object, int nCopies) {
        _mods++;
        if (nCopies > 0) {
            int count = (nCopies + getCount(object));
            _map.put(object, new Integer(count));
            _total += nCopies;
            return (count == nCopies);
        } else {
            return false;
        }
    }

    /**
     * Invokes {@link #add(Object)} for each element in the given collection.
     *
     * @param coll  the collection to add
     * @return <code>true if this call changed the bag
     */
    public boolean addAll(Collection coll) {
        boolean changed = false;
        Iterator i = coll.iterator();
        while (i.hasNext()) {
            boolean added = add(i.next());
            changed = changed || added;
        }
        return changed;
    }

    /**
     * Clears the bag by clearing the underlying map.
     */
    public void clear() {
        _mods++;
        _map.clear();
        _total = 0;
    }

    /**
     * Determines if the bag contains the given element by checking if the
     * underlying map contains the element as a key.
     *
     * @param object  the object to search for
     * @return true if the bag contains the given element
     */
    public boolean contains(Object object) {
        return _map.containsKey(object);
    }

    /**
     * Determines if the bag contains the given elements.
     * 
     * @param coll  the collection to check against
     * @return <code>true if the Bag contains all the collection
     */
    public boolean containsAll(Collection coll) {
        return containsAll(new HashBag(coll));
    }

    /**
     * Returns <code>true if the bag contains all elements in
     * the given collection, respecting cardinality.
     * 
     * @param other  the bag to check against
     * @return <code>true if the Bag contains all the collection
     */
    public boolean containsAll(Bag other) {
        boolean result = true;
        Iterator i = other.uniqueSet().iterator();
        while (i.hasNext()) {
            Object current = i.next();
            boolean contains = getCount(current) >= other.getCount(current);
            result = result && contains;
        }
        return result;
    }

    /**
     * Returns true if the given object is not null, has the precise type 
     * of this bag, and contains the same number of occurrences of all the
     * same elements.
     *
     * @param object  the object to test for equality
     * @return true if that object equals this bag
     */
    public boolean equals(Object object) {
        if (object == this) {
            return true;
        }
        if (object instanceof Bag == false) {
            return false;
        }
        Bag other = (Bag) object;
        if (other.size() != size()) {
            return false;
        }
        for (Iterator it = _map.keySet().iterator(); it.hasNext();) {
            Object element = it.next();
            if (other.getCount(element) != getCount(element)) {
                return false;
            }
        }
        return true;
    }

    /**
     * Returns the hash code of the underlying map.
     *
     * @return the hash code of the underlying map
     */
    public int hashCode() {
        return _map.hashCode();
    }

    /**
     * Returns true if the underlying map is empty.
     *
     * @return true if there are no elements in this bag
     */
    public boolean isEmpty() {
        return _map.isEmpty();
    }

    public Iterator iterator() {
        return new BagIterator(this, extractList().iterator());
    }

    static class BagIterator implements Iterator {
        private DefaultMapBag _parent = null;
        private Iterator _support = null;
        private Object _current = null;
        private int _mods = 0;

        public BagIterator(DefaultMapBag parent, Iterator support) {
            _parent = parent;
            _support = support;
            _current = null;
            _mods = parent.modCount();
        }

        public boolean hasNext() {
            return _support.hasNext();
        }

        public Object next() {
            if (_parent.modCount() != _mods) {
                throw new ConcurrentModificationException();
            }
            _current = _support.next();
            return _current;
        }

        public void remove() {
            if (_parent.modCount() != _mods) {
                throw new ConcurrentModificationException();
            }
            _support.remove();
            _parent.remove(_current, 1);
            _mods++;
        }
    }

    public boolean remove(Object object) {
        return remove(object, getCount(object));
    }

    public boolean remove(Object object, int nCopies) {
        _mods++;
        boolean result = false;
        int count = getCount(object);
        if (nCopies <= 0) {
            result = false;
        } else if (count > nCopies) {
            _map.put(object, new Integer(count - nCopies));
            result = true;
            _total -= nCopies;
        } else { // count > 0 && count <= i  
            // need to remove all
            result = (_map.remove(object) != null);
            _total -= count;
        }
        return result;
    }

    public boolean removeAll(Collection coll) {
        boolean result = false;
        if (coll != null) {
            Iterator i = coll.iterator();
            while (i.hasNext()) {
                boolean changed = remove(i.next(), 1);
                result = result || changed;
            }
        }
        return result;
    }

    /**
     * Remove any members of the bag that are not in the given
     * bag, respecting cardinality.
     *
     * @param coll  the collection to retain
     * @return true if this call changed the collection
     */
    public boolean retainAll(Collection coll) {
        return retainAll(new HashBag(coll));
    }

    /**
     * Remove any members of the bag that are not in the given
     * bag, respecting cardinality.
     * @see #retainAll(Collection)
     * 
     * @param other  the bag to retain
     * @return <code>true if this call changed the collection
     */
    public boolean retainAll(Bag other) {
        boolean result = false;
        Bag excess = new HashBag();
        Iterator i = uniqueSet().iterator();
        while (i.hasNext()) {
            Object current = i.next();
            int myCount = getCount(current);
            int otherCount = other.getCount(current);
            if (1 <= otherCount && otherCount <= myCount) {
                excess.add(current, myCount - otherCount);
            } else {
                excess.add(current, myCount);
            }
        }
        if (!excess.isEmpty()) {
            result = removeAll(excess);
        }
        return result;
    }

    /**
     * Returns an array of all of this bag's elements.
     *
     * @return an array of all of this bag's elements
     */
    public Object[] toArray() {
        return extractList().toArray();
    }

    /**
     * Returns an array of all of this bag's elements.
     *
     * @param array  the array to populate
     * @return an array of all of this bag's elements
     */
    public Object[] toArray(Object[] array) {
        return extractList().toArray(array);
    }

    /**
     * Returns the number of occurrence of the given element in this bag
     * by looking up its count in the underlying map.
     *
     * @param object  the object to search for
     * @return the number of occurrences of the object, zero if not found
     */
    public int getCount(Object object) {
        int result = 0;
        Integer count = MapUtils.getInteger(_map, object);
        if (count != null) {
            result = count.intValue();
        }
        return result;
    }

    /**
     * Returns an unmodifiable view of the underlying map's key set.
     *
     * @return the set of unique elements in this bag
     */
    public Set uniqueSet() {
        return UnmodifiableSet.decorate(_map.keySet());
    }

    /**
     * Returns the number of elements in this bag.
     *
     * @return the number of elements in this bag
     */
    public int size() {
        return _total;
    }

    /**
     * Actually walks the bag to make sure the count is correct and
     * resets the running total
     * 
     * @return the current total size
     */
    protected int calcTotalSize() {
        _total = extractList().size();
        return _total;
    }

    /**
     * Utility method for implementations to set the map that backs
     * this bag. Not intended for interactive use outside of
     * subclasses.
     */
    protected void setMap(Map map) {
        if (map == null || map.isEmpty() == false) {
            throw new IllegalArgumentException("The map must be non-null and empty");
        }
        _map = map;
    }

    /**
     * Utility method for implementations to access the map that backs
     * this bag. Not intended for interactive use outside of
     * subclasses.
     */
    protected Map getMap() {
        return _map;
    }

    /**
     * Create a list for use in iteration, etc.
     */
    private List extractList() {
        List result = new ArrayList();
        Iterator i = uniqueSet().iterator();
        while (i.hasNext()) {
            Object current = i.next();
            for (int index = getCount(current); index > 0; index--) {
                result.add(current);
            }
        }
        return result;
    }

    /**
     * Return number of modifications for iterator.
     * 
     * @return the modification count
     */
    private int modCount() {
        return _mods;
    }

    /**
     * Implement a toString() method suitable for debugging.
     * 
     * @return a debugging toString
     */
    public String toString() {
        StringBuffer buf = new StringBuffer();
        buf.append("[");
        Iterator i = uniqueSet().iterator();
        while (i.hasNext()) {
            Object current = i.next();
            int count = getCount(current);
            buf.append(count);
            buf.append(":");
            buf.append(current);
            if (i.hasNext()) {
                buf.append(",");
            }
        }
        buf.append("]");
        return buf.toString();
    }
    
}

Other Commons Collections examples (source code examples)

Here is a short list of links related to this Commons Collections DefaultMapBag.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.