2010-06-12 3 views
13

A Google CollectionsMultiset представляет собой набор элементов, каждый из которых имеет счет (то есть может присутствовать несколько раз).Найти N элементов в мультимножестве из коллекций Google?

Я не могу сказать вам, сколько раз я хочу сделать следующее

  1. Сделать гистограмму (точно MultiSet)
  2. Получить верхние N элементов по количеству строк из гистограммы

Примеры: 10 лучших URL-адресов (по указанным выше раз), 10 лучших тегов (по # раз применен), ...

Что такое канонический способ сделать # 2 с учетом множества коллекций Google Collections Multiset?

Here это сообщение в блоге об этом, но этот код не совсем то, что я хочу. Во-первых, он возвращает все, а не только сверху N. Во-вторых, он копирует (можно ли избежать копирования?). В-третьих, я обычно хочу детерминированный сорт, т. Е. Тай-брейк, если подсчеты равны. Другой нит: это не статично, и т.д.

ответ

4

я писал методы с базовые функции, о которых вы просите, за исключением того, что они выполняют копии и не имеют детерминированной логики развязывания. В настоящее время они являются внутренними для Google, но в какой-то момент мы можем их открыть. Этот Guava issue имеет подписи метода.

Их алгоритм похож на сообщение в блоге: сортировка списка записей. Было бы быстрее, но сложнее, использовать лучше selection algorithm.

EDIT: с гуавы 11, это implemented

+0

как использовать его для получения N элементов? –

3

Чтобы дать другую перспективу для людей, чтобы комментировать, я выложу немного измененную версию в блоге я ссылка:

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; 
    } 
} 
+0

Если я правильно понимаю, это решение будет копировать и сортировать всю коллекцию каждый раз, когда вы хотите, чтобы получить верхние N элементов. Я не уверен, каковы ваши требования, но решение heap-sort-ish превосходит это как во времени, так и в пространстве, поэтому я не уверен, в чем преимущество. – danben

+0

Вы оптимизируетесь для скорости, я ищу наименьшее количество строк кода, написанных мной. – dfrankow

+0

Я вижу - это было непонятно с вашего поста, тем более, что вы спрашивали об избежании копирования. – danben