Найдите верхние N элементов в Multiset из коллекций Google?
A Коллекции Google Multiset - это набор элементов, каждый из которых имеет счет (т.е. может присутствовать несколько раз).
Я не могу сказать, сколько раз я хочу сделать следующее
- Сделайте гистограмму (точно Multiset)
- Получить верхние N элементов по счету с гистограммы
Примеры: первые 10 URL-адресов (по указанным выше раз), топ-10 тегов (с использованием # раза),...
Что такое канонический способ сделать # 2 с помощью набора коллекций Google Collections Multiset?
Здесь - это сообщение в блоге об этом, но этот код не совсем то, что я хочу. Во-первых, он возвращает все, а не только сверху N. Во-вторых, он копирует (можно ли избежать копирования?). В-третьих, я обычно хочу детерминированный сорт, т.е. Тай-брейк, если подсчеты равны. Другие гниды: это не статические и т.д.
Ответы
Ответ 1
Я писал методы с базовой функциональностью, о которой вы просите, за исключением того, что они выполняют копии и не имеют детерминированной логики развязывания. В настоящее время они являются внутренними для Google, но в какой-то момент мы можем их открыть. Этот Guava issue имеет сигнатуры метода.
Их алгоритм похож на сообщение в блоге: сортировка списка записей. Было бы быстрее, но сложнее использовать более качественный алгоритм выбора.
EDIT: начиная с Guava 11, это реализовано
Ответ 2
Чтобы дать другим людям возможность высказаться, я опубликую немного измененную версию сообщения в блоге, на которое я ссылаюсь:
package com.blueshiftlab.twitterstream.summarytools;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Multiset;
import com.google.common.collect.Ordering;
import com.google.common.collect.Multiset.Entry;
public class Multisets {
// Don't construct one
private Multisets() {
}
public static <T> ImmutableList<Entry<T>> sortedByCount(Multiset<T> multiset) {
Ordering<Multiset.Entry<T>> countComp = new Ordering<Multiset.Entry<T>>() {
public int compare(Multiset.Entry<T> e1, Multiset.Entry<T> e2) {
return e2.getCount() - e1.getCount();
}
};
return countComp.immutableSortedCopy(multiset.entrySet());
}
public static <T> ImmutableList<Entry<T>> topByCount(Multiset<T> multiset,
int max) {
ImmutableList<Entry<T>> sortedByCount = sortedByCount(multiset);
if (sortedByCount.size() > max) {
sortedByCount = sortedByCount.subList(0, max);
}
return sortedByCount;
}
}