如果你真的想避免循环遍历 Multiset 的条目,你可以创建一个 Map 的视图:
public class MultisetMapView<E> implements Map<E, Integer> {
private Multiset<E> delegate;
public MultisetMapView(Multiset<E> delegate) {
this.delegate = delegate;
}
public int size() {
return delegate.size();
}
public boolean isEmpty() {
return delegate.isEmpty();
}
public boolean containsKey(Object key) {
return delegate.contains(key);
}
public boolean containsValue(Object value) {
throw new UnsupportedOperationException();
}
public Integer get(Object key) {
return delegate.count(key);
}
public Integer put(E key, Integer value) {
return delegate.setCount(key, value);
}
public Integer remove(Object key) {
int count = delegate.count(key);
delegate.remove(key);
return count;
}
public void putAll(Map<? extends E, ? extends Integer> m) {
for (Entry<? extends E, ? extends Integer> entry : m.entrySet()) {
delegate.setCount(entry.getKey(), entry.getValue());
}
}
public void clear() {
delegate.clear();
}
public Set<E> keySet() {
return delegate.elementSet();
}
public Collection<Integer> values() {
throw new UnsupportedOperationException();
}
public Set<java.util.Map.Entry<E, Integer>> entrySet() {
Set<java.util.Map.Entry<E, Integer>> entrySet = Sets.newHashSet();
for (E e : delegate) {
delegate.count(e);
entrySet.add(Maps.immutableEntry(e, delegate.count(e)));
}
return entrySet;
}
}
在我的实现中,我拒绝实现containsValue 和values 方法,因为它们在上下文中没有用。如果需要,可以通过遍历条目并检查遇到的元素的count 来实现这些。
再一次,您可以在这个 JUnit 案例中看到这一点:
@Test
public void testConvert() {
HashMultiset<String> hashMultiset = HashMultiset.create();
hashMultiset.add("a");
hashMultiset.add("a");
hashMultiset.add("a");
hashMultiset.add("b");
hashMultiset.add("c");
Map<String, Integer> map = new MultisetMapView<String>(hashMultiset);
assertEquals((Integer) 3, map.get("a"));
assertEquals((Integer) 1, map.get("b"));
assertEquals((Integer) 1, map.get("c"));
}