org.solovyev.common.collections.multiset.AbstractMapManyInstancesMultiSet Maven / Gradle / Ivy
package org.solovyev.common.collections.multiset;
import org.jetbrains.annotations.NotNull;
import java.util.*;
/**
* User: serso
* Date: 7/9/12
* Time: 6:28 PM
*/
abstract class AbstractMapManyInstancesMultiSet extends AbstractMultiSet implements ManyInstancesMultiSet {
@NotNull
private final Map> backingMap;
protected AbstractMapManyInstancesMultiSet(@NotNull Map> backingMap) {
this.backingMap = backingMap;
}
@Override
public int count(E e) {
return get(e).size();
}
// always returns unmodifiable list
@NotNull
private List get(E e) {
final List list = backingMap.get(e);
return list == null ? Collections.emptyList() : Collections.unmodifiableList(list);
}
@NotNull
@Override
public Collection getAll(E e) {
return get(e);
}
@NotNull
@Override
public Set toElementSet() {
final Set result = new HashSet();
for (Map.Entry> entry : backingMap.entrySet()) {
final List list = entry.getValue();
if (list != null && !list.isEmpty()) {
result.add(entry.getKey());
}
}
return result;
}
@Override
public boolean add(E e, int count) {
MultiSets.checkAdd(count);
final List oldList = get(e);
final List newList = new ArrayList(oldList);
for (int i = 0; i < count; i++) {
newList.add(e);
}
this.backingMap.put(e, newList);
return count > 0;
}
@Override
public int remove(E e, int count) {
MultiSets.checkRemove(count);
final List list = backingMap.get(e);
final int result = list == null ? 0 : list.size();
int i = 0;
if (list != null) {
for (Iterator it = list.iterator(); it.hasNext() && i < count; i++) {
it.next();
it.remove();
}
}
return result;
}
@Override
public int size() {
int result = 0;
for (List list : backingMap.values()) {
result += list.size();
}
return result;
}
@Override
public boolean contains(Object o) {
return !get((E) o).isEmpty();
}
@Override
public Iterator iterator() {
return new ValueIterator();
}
private class ValueIterator implements Iterator {
private final Iterator>> keyIterator;
private E key;
private Collection collection;
private Iterator valueIterator;
private ValueIterator() {
keyIterator = backingMap.entrySet().iterator();
if (keyIterator.hasNext()) {
findValueIteratorAndKey();
} else {
valueIterator = (Iterator) MultiSets.EMPTY_MODIFIABLE_ITERATOR;
}
}
void findValueIteratorAndKey() {
Map.Entry> entry = keyIterator.next();
key = entry.getKey();
collection = entry.getValue();
valueIterator = collection.iterator();
}
@Override
public boolean hasNext() {
return keyIterator.hasNext() || valueIterator.hasNext();
}
@Override
public E next() {
if (!valueIterator.hasNext()) {
findValueIteratorAndKey();
}
return valueIterator.next();
}
@Override
public void remove() {
valueIterator.remove();
if (collection.isEmpty()) {
keyIterator.remove();
}
}
}
@Override
public void clear() {
this.backingMap.clear();
}
}