Я использовал Multiset
для имеют легкий доступ к частоте элементов, но я понимаю, что есть Collections#frequency(Collection<?>, Object)
, который делает то же самое для любой коллекции. Какой тогда смысл использовать Multiset
? Является ли здесь проблемой производительность?
Использование мультимножеств Guava или Collections.frequency ()?
Ответы (1)
Документация по Guava для 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
. Для получения подробной информации о том, насколько это более эффективно, чем повторение всей коллекции, взгляните на этот ответ: Как Java HashMap обрабатывает разные объекты с одним и тем же хеш-кодом?.
код Guava выглядит следующим образом
public int count(@Nullable Object element) {
Count frequency = Maps.safeGet(backingMap, element);
return (frequency == null) ? 0 : frequency.get();
}
Точно так же для TreeMultiset
, который поддерживает порядок своих элементов и поддерживается деревом AVL, count
можно получить за O(log(n)) шагов вместо O(n), где n — размер коллекции. код Guava заключается в следующем:
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;
}
}
Multiset
содержит один элемент миллион раз, Collections.frequency
будет повторять его миллион раз, в то время как Multiset
просто находит элемент (применяется ваше обозначение Big-O) и говорит один миллион.
- person maaartinus; 09.12.2014
n
обычно относится к количеству различных элементов, тогда как, например, для List
это будет относиться к общему количеству элементов, различных или нет.
- person Louis Wasserman; 09.12.2014