以元素频率的顺序迭代Multiset的最简单方法是什么?

Jon*_*nik 32 java multiset guava

考虑这个打印出一些设备类型统计数据的例子.("DeviceType"是一个带有十二个值的枚举.)

Multiset<DeviceType> histogram = getDeviceStats();
for (DeviceType type : histogram.elementSet()) {
    System.out.println(type + ": " + histogram.count(type));
}
Run Code Online (Sandbox Code Playgroud)

以频率顺序打印不同元素的最简单,最优雅的方法是什么(最常见的类型是第一种)?

随着快速浏览一下Multiset界面,有一个为这个没有现成的方法,并没有番石榴的的Multiset实现(HashMultiset,TreeMultiset,等)似乎自动保持要素频率有序无论是.

Lou*_*man 39

我刚刚将此功能添加到Guava,请参阅此处的Javadoc.

编辑:Multisets.copyHighestCountFirst()根据原始问题的用法示例:

Multiset<DeviceType> histogram = getDeviceStats();
for (DeviceType type : Multisets.copyHighestCountFirst(histogram).elementSet()) {
    System.out.println(type + ": " + histogram.count(type));
}
Run Code Online (Sandbox Code Playgroud)

  • 嗯,非常好,但是能够选择升序/降序排序会更好. (6认同)

Sea*_*oyd 7

这是一个返回一个List条目的方法,按频率排序(UPDATE:使用一个标志来切换升序/降序并使用Guava最喜欢的玩具:Enum Singleton PatternEffective Java中的第3项所示):

private enum EntryComp implements Comparator<Multiset.Entry<?>>{
    DESCENDING{
        @Override
        public int compare(final Entry<?> a, final Entry<?> b){
            return Ints.compare(b.getCount(), a.getCount());
        }
    },
    ASCENDING{
        @Override
        public int compare(final Entry<?> a, final Entry<?> b){
            return Ints.compare(a.getCount(), b.getCount());
        }
    },
}

public static <E> List<Entry<E>> getEntriesSortedByFrequency(
    final Multiset<E> ms, final boolean ascending){
    final List<Entry<E>> entryList = Lists.newArrayList(ms.entrySet());
    Collections.sort(entryList, ascending
        ? EntryComp.ASCENDING
        : EntryComp.DESCENDING);
    return entryList;
}
Run Code Online (Sandbox Code Playgroud)

测试代码:

final Multiset<String> ms =
    HashMultiset.create(Arrays.asList(
        "One",
        "Two", "Two",
        "Three", "Three", "Three",
        "Four", "Four", "Four", "Four"
    ));

System.out.println("ascending:");
for(final Entry<String> entry : getEntriesSortedByFrequency(ms, true)){
    System.out.println(MessageFormat.format("{0} ({1})",
        entry.getElement(), entry.getCount()));
}

System.out.println("descending:");
for(final Entry<String> entry : getEntriesSortedByFrequency(ms, false)){
    System.out.println(MessageFormat.format("{0} ({1})",
        entry.getElement(), entry.getCount()));
}
Run Code Online (Sandbox Code Playgroud)

输出:

升序:
一(1)
两(2)
三(3)
四(4)
降序:
四(4)
三(3)
二(2)
一(1)

  • (Guava非常酷;之前我没有注意到`Ints`类.再看看API文档,`Files`对我来说也是新手 - 类似于Commons IO的util集合,除了泛型支持不知何故*整体更干净.) (2认同)