我使用Multiset
可以轻松访问元素的频率,但是我意识到有Collections#frequency(Collection<?>, Object)
可以对任何集合进行相同的操作。那么使用Multiset
有什么意义呢?性能是这里的问题吗?
最佳答案
Multiset#count()的番石榴文档
不得不说:
请注意,对于基于Object.equals(java.lang.Object)的多重集,此结果与Collections.frequency(java.util.Collection,java.lang.Object)的结果相同(可能表现较差)。
因此,是的,我怀疑性能是这里的问题。
我认为Multiset#count
效率更高,因为Collections#frequency
遍历整个集合。对于要检查其频率的对象o,它将遍历集合中的所有元素e并检查(o == null ? e == null : o.equals(e))
。
对于Multiset(这是一个接口),count
的确切实现取决于类。例如,如果它是HashMultiset
,则它由HashMap
支持。有关如何比遍历整个集合更有效的详细信息,请查看以下答案:How does a Java HashMap handle different objects with the same hash code?。
Guava code如下
public int count(@Nullable Object element) {
Count frequency = Maps.safeGet(backingMap, element);
return (frequency == null) ? 0 : frequency.get();
}
同样,对于保持其元素顺序并由AVL树支持的
TreeMultiset
,可以用O(log(n))步而不是O(n)获得count
,其中n是大小的集合。 Guava code如下:public int count(@Nullable Object element) {
try {
@SuppressWarnings("unchecked")
E e = (E) element;
AvlNode<E> root = rootReference.get();
if (!range.contains(e) || root == null) {
return 0;
}
return root.count(comparator(), e);
} catch (ClassCastException e) {
return 0;
} catch (NullPointerException e) {
return 0;
}
}