
org.solovyev.common.collections.multiset.AbstractMapManyInstancesMultiSet Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2013 serso aka se.solovyev
*
* Licensed 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.
*
* ---------------------------------------------------------------------
* Contact details
*
* Email: [email protected]
* Site: http://se.solovyev.org
*/
package org.solovyev.common.collections.multiset;
import javax.annotation.Nonnull;
import java.util.*;
abstract class AbstractMapManyInstancesMultiSet extends AbstractMultiSet implements ManyInstancesMultiSet {
@Nonnull
private final Map> backingMap;
protected AbstractMapManyInstancesMultiSet(@Nonnull Map> backingMap) {
this.backingMap = backingMap;
}
@Override
public int count(E e) {
return get(e).size();
}
// always returns unmodifiable list
@Nonnull
private List get(E e) {
final List list = backingMap.get(e);
return list == null ? Collections.emptyList() : Collections.unmodifiableList(list);
}
@Nonnull
@Override
public Collection getAll(E e) {
return get(e);
}
@Nonnull
@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 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();
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();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy