BinaryMap
class implements a map from objects to
* integer objects where the only value is the integer with value 1.
* Instances of this class are typically returned by boolean feature
* extractors, who return a map with only 1 values, because the 0
* values are implicit.
*
* Binary maps are based on a set of keys that map to 1. Thus * they are more space efficient than Java's utility maps such * as tree maps or hash maps. The underlying set implementation is * pluggable, but must be mutable if the resulting binary map * is to be mutable. * *
Modifiability through the entry set, key set, and values * collection is fully supported through their respective iterators * and through the collections themselves. The map entries making * up the entry set may not have their values modified. * *
Note that this method is not part of the {@link Map} * interface. * * @param e Element added to the map with value 1. * @return {@code true} if the map didn't already contain the * element. * @throws UnsupportedOperationException If the underlying set of * positive elements does not support {@code Collection.add}. */ public boolean add(E e) { return mPositiveSet.add(e); } /** * Returns the set of keys mapping to 1. This set is backed by * this map, so changes to the set are reflected in the map and * vice-versa. * *
If the underlying set is not modifiable, attempts to * modify the key set will raise unsupported operation exceptions. * *
Note that results are undefined in the middle of an * iterator, which will likely throw concurrent modification, null * pointer, or array index out of bounds exceptions. Therefore, * access to the key set must be synchronized in the same way * access to the underlying set. * *
Further note that unlike the specification in {@link Map},
* the returned keyset supports the {@link Collection#add(Object)} and
* {@link Collection#addAll(Collection)}. Adding elements to the key set
* is the same as adding them through the {@link #add(Object)}
* method of this class.
*
* @return The set of keys mapping to one.
*/
public Set If the underlying set of positive elements does not
* support these modification operations, they will throw an
* unsupported operation exception.
*
* Implementation Note: The {@code Map.Entry} elements
* are created as necessary by the entry set using a relatively
* efficient implementation of entries that only stores the key.
* Accessing the key set is more efficient.
*
* @return The set of mappings for this map.
*/
@Override
public Set The constant {@link #ONE} is used for the return
* value.
*
* @param key The element whose value is returned.
* @return 1 if the element is mapped to 1, and {@code null}
* otherwise.
*/
@Override
public Integer get(Object key) {
return mPositiveSet.contains(key)
? ONE
: null;
}
/**
* Remove the mapping with the specified key if it is present, returning
* the previous value, or {@code null} if it was previously undefined.
*
* @param key Key of mapping to remove.
* @return The value 1 if the key is already present, and {@code
* null} otherwise.
* @throws UnsupportedOperationException If the underlying set for
* this map does not support the {@link Set#remove(Object)} operation.
*/
@Override
public Integer remove(Object key) {
return mPositiveSet.remove(key)
? ONE
: null;
}
/**
* Returns the size of this mapping.
*
* @return Size of this mapping.
*/
@Override
public int size() {
return mPositiveSet.size();
}
/**
* Returns an immutable collection view of the values for this
* map. The resulting collecton will be empty if the map is
* entry, or contain the single value {@link #ONE} if the map is
* not empty.
*/
@Override
public Collection The implementation just delegates the clear operation to the
* contained set.
*
* @throws UnsupportedOperationException If the clear operation
* is not supported by the contained set.
*/
@Override
public void clear() {
mPositiveSet.clear();
}
/**
* Returns {@code true} if this mapping contains a mapping
* for the specified object.
*
* This method delegates to the underlying positive set's
* {@code Collection.contains} method.
*
* @param o Object to teset.
* @return {@code true} if it is mapped by this mapping.
* @throws ClassCastException If the underlying set throws
* a class cast when checking the specified object for
* membership.
*/
@Override
public boolean containsKey(Object o) {
return mPositiveSet.contains(o);
}
/**
* Returns {@code true} if this map contains a mapping
* from some key to the specified value.
*
* Note that the only object for which this map may
* return true is the {@code Integer} with value 1.
*
* @param o Object to test.
* @return {@code true} if this map contains a mapping
* from some object to this value.
*/
@Override
public boolean containsValue(Object o) {
return ONE.equals(o) && !isEmpty();
}
/**
* Returns {@code true} if this mapping is empty.
*
* @return {@code true} if this mapping is empty.
*/
@Override
public boolean isEmpty() {
return mPositiveSet.isEmpty();
}
/**
* Adds the mapping of the specified object to the specified
* value if the specified number is the {@code Integer} with
* value 1.
*
* @param e Key for the mapping.
* @param n Value for the mapping.
* @throws IllegalArgumentException If the specified integer
* does not have value 1.
*/
@Override
public Integer put(E e, Integer n) {
if (!ONE.equals(n))
throw new IllegalArgumentException();
return mPositiveSet.add(e) ? null : ONE;
}
class Values extends AbstractCollection