com.google.common.collect
Class ConcurrentMultiset<E>

java.lang.Object
  extended by java.util.AbstractCollection<E>
      extended by com.google.common.collect.AbstractMultiset<E>
          extended by com.google.common.collect.ConcurrentMultiset<E>
All Implemented Interfaces:
Multiset<E>, Serializable, Iterable<E>, Collection<E>

public final class ConcurrentMultiset<E>
extends AbstractMultiset<E>
implements Serializable

A multiset that supports concurrent modifications and that provides atomic versions of most Multiset operations (exceptions where noted).

This implementation is backed by a ConcurrentMap, and several of its properties will depend on the behavior of this backing map: for example, it can contain only values that are legal keys for the backing map. Thus, when using the default ConcurrentHashMap, this implementation cannot contain null.

An instance of this class is serializable, as long as all of its elements are serializable and the instance wasn't created by passing a non-serializable map to ConcurrentMultiset(ConcurrentMap).

Author:
Cliff L. Biffle
See Also:
Serialized Form

Nested Class Summary
 
Nested classes/interfaces inherited from interface com.google.common.collect.Multiset
Multiset.Entry<E>
 
Constructor Summary
ConcurrentMultiset()
          Creates an empty instance using a ConcurrentHashMap to store elements and their counts.
ConcurrentMultiset(Collection<? extends E> collection)
          Creates an instance using a ConcurrentHashMap to store elements and their counts, and initially containing all the elements from a given collection.
ConcurrentMultiset(ConcurrentMap<E,Integer> countMap)
          Creates an instance using countMap to store elements and their counts.
 
Method Summary
 boolean add(E element, int occurrences)
          Adds a number of occurrences of the specified element to this multiset.
 int count(Object element)
          Returns the number of occurrences of element in this multiset.
 Set<E> elementSet()
          Returns the set of distinct elements contained in this multiset.
 Set<Multiset.Entry<E>> entrySet()
          Returns a view of the contents of this multiset, grouped into Multiset.Entry instances, each providing an element of the multiset and the count of that element.
 int remove(Object element, int occurrences)
          Removes a number of occurrences of the specified element from this multiset.
 int removeAllOccurrences(Object element)
          Removes all occurrences of the specified element from this multiset.
 boolean removeExactly(Object element, int occurrences)
          Removes exactly the specified number of occurrences of element, or makes no change if this is not possible.
 int setCount(E element, int count)
          Adds or removes occurrences of element such that the count(java.lang.Object) of the element becomes count.
 boolean setCount(E element, int oldCount, int newCount)
          Sets the number of occurrences of element to newCount, but only if the count is currently oldCount.
 int size()
          
 Object[] toArray()
           
<T> T[]
toArray(T[] array)
           
 
Methods inherited from class com.google.common.collect.AbstractMultiset
add, addAll, clear, contains, containsAll, createElementSet, equals, hashCode, isEmpty, iterator, remove, removeAll, retainAll, toString
 
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
 

Constructor Detail

ConcurrentMultiset

public ConcurrentMultiset()
Creates an empty instance using a ConcurrentHashMap to store elements and their counts.

The ConcurrentHashMap will have default capacity, load factor, and concurrency settings. For more control, use ConcurrentMultiset(ConcurrentMap).


ConcurrentMultiset

public ConcurrentMultiset(Collection<? extends E> collection)
Creates an instance using a ConcurrentHashMap to store elements and their counts, and initially containing all the elements from a given collection.

The ConcurrentHashMap will have default capacity, load factor, and concurrency settings. For more control, use ConcurrentMultiset(ConcurrentMap).


ConcurrentMultiset

public ConcurrentMultiset(ConcurrentMap<E,Integer> countMap)
Creates an instance using countMap to store elements and their counts.

This instance will assume ownership of countMap, and other code should not maintain references to the map or modify it in any way.

Parameters:
countMap - backing map for storing the elements in the multiset and their counts. Must be empty.
Throws:
IllegalArgumentException - if countMap is not empty
Method Detail

count

public int count(@Nullable
                 Object element)
Returns the number of occurrences of element in this multiset.

Specified by:
count in interface Multiset<E>
Overrides:
count in class AbstractMultiset<E>
Parameters:
element - the element to look for
Returns:
the nonnegative number of occurrences of the element

toArray

public Object[] toArray()
Specified by:
toArray in interface Collection<E>
Overrides:
toArray in class AbstractCollection<E>

toArray

public <T> T[] toArray(T[] array)
Specified by:
toArray in interface Collection<E>
Overrides:
toArray in class AbstractCollection<E>

add

public boolean add(E element,
                   int occurrences)
Adds a number of occurrences of the specified element to this multiset.

To succeed, element must be a legal key in the backing map. In the case of the default ConcurrentHashMap, this means it must not be null, but other Map implementations may allow null.

Specified by:
add in interface Multiset<E>
Overrides:
add in class AbstractMultiset<E>
Parameters:
element - the element to add
occurrences - the number of occurrences to add
Returns:
true if the collection changed as a result (this should always be the case unless occurrences is zero)
Throws:
IllegalArgumentException - if occurrences is negative, or if the resulting amount would exceed Integer.MAX_VALUE

remove

public int remove(@Nullable
                  Object element,
                  int occurrences)
Removes a number of occurrences of the specified element from this multiset. If the multiset contains fewer than this number of occurrences to begin with, all occurrences will be removed.

Specified by:
remove in interface Multiset<E>
Overrides:
remove in class AbstractMultiset<E>
Parameters:
element - the element whose occurrences should be removed
occurrences - the number of occurrences of this element to remove
Returns:
the number of occurrences that were successfully removed (zero if the element was not present)
Throws:
IllegalArgumentException - if occurrences is negative

removeAllOccurrences

public int removeAllOccurrences(@Nullable
                                Object element)
Removes all occurrences of the specified element from this multiset. This method complements Multiset.remove(Object), which removes only one occurrence at a time.

Specified by:
removeAllOccurrences in interface Multiset<E>
Overrides:
removeAllOccurrences in class AbstractMultiset<E>
Parameters:
element - the element whose occurrences should all be removed
Returns:
the number of occurrences successfully removed, possibly zero

size

public int size()

This implementation iterates across Multiset.entrySet() and sums the counts of the entries.

If the data in the multiset is modified by any other threads during this method, it is undefined which (if any) of these modifications will be reflected in the result.

Specified by:
size in interface Collection<E>
Overrides:
size in class AbstractMultiset<E>

setCount

public int setCount(E element,
                    int count)
Adds or removes occurrences of element such that the count(java.lang.Object) of the element becomes count.

Returns:
the count of element in the multiset before this call
Throws:
IllegalArgumentException - if count is negative

setCount

public boolean setCount(E element,
                        int oldCount,
                        int newCount)
Sets the number of occurrences of element to newCount, but only if the count is currently oldCount. If element does not appear in the multiset exactly oldCount times, no changes will be made.

Returns:
true if the change was successful. This usually indicates that the multiset has been modified, but not always: in the case that oldCount == newCount, the method will return true if the condition was met.
Throws:
IllegalArgumentException - if oldCount or newCount is negative

removeExactly

public boolean removeExactly(@Nullable
                             Object element,
                             int occurrences)
Removes exactly the specified number of occurrences of element, or makes no change if this is not possible.

This method, in contrast to remove(Object, int), has no effect when the element count is smaller than occurrences.

Parameters:
element - the element to remove
occurrences - the number of occurrences of element to remove
Returns:
true if the removal was possible (including if occurrences is zero)

elementSet

public Set<E> elementSet()
Description copied from class: AbstractMultiset
Returns the set of distinct elements contained in this multiset. The element set is backed by the same data as the multiset, so any change to either is immediately reflected in the other. The order of the elements in the element set is unspecified.

If the element set supports any removal operations, these necessarily cause all occurrences of the removed element(s) to be removed from the multiset. Implementations are not expected to support the add operations, although this is possible.

A common use for the element set is to find the number of distinct elements in the multiset: elementSet().size().

The returned set's methods are implemented by calling Multiset.entrySet() methods.

Specified by:
elementSet in interface Multiset<E>
Overrides:
elementSet in class AbstractMultiset<E>
Returns:
a view of the set of distinct elements in this multiset

entrySet

public Set<Multiset.Entry<E>> entrySet()
Description copied from interface: Multiset
Returns a view of the contents of this multiset, grouped into Multiset.Entry instances, each providing an element of the multiset and the count of that element. This set contains exactly one entry for each distinct element in the multiset (thus it always has the same size as the Multiset.elementSet()). The order of the elements in the element set is unspecified.

The entry set is backed by the same data as the multiset, so any change to either is immediately reflected in the other. However, multiset changes may or may not be reflected in any Entry instances already retrieved from the entry set (this is implementation-dependent). Furthermore, implementations are not required to support modifications to the entry set at all, and the Entry instances themselves don't even have methods for modification. See the specific implementation class for more details on how its entry set handles modifications.

Specified by:
entrySet in interface Multiset<E>
Specified by:
entrySet in class AbstractMultiset<E>
Returns:
a set of entries representing the data of this multiset