我可能想将问题改为“我如何选择Multiset中的第一项?”因为似乎Multiset已按照频率排序。
我有一个Multiset myList = Multiset.create();
[maa00 mfnt11 malignlft mbold mlt18 mfl x 3, caa00 cfnt11 calignlft cbold clt17 cfl]
我找不到像myList.getIndex(0)这样的方法。请注意,最后,我需要具有最大频率的元素数。
这是否有任何一个班轮?或者我必须做那个迭代?
更新: 我使用以下方式获得最高频率:
myList.count(Multisets.copyHighestCountFirst(myList).asList().get(0)));
但这太慢了。你能告诉我,我到底应该使用什么?
更新1:使用上面的copyHighestCountFirst方法证明太慢了。在循环的一个实例中,在没有它的情况下使用80 +毫秒而不是平均40毫秒。 在大循环中,我应该更喜欢简单的迭代吗?
更新2:使用以下工具:
myList.count(myList.entrySet().iterator().next().getElement())
对性能几乎没有影响。我仍然想知道是否有更好的方法来做到这一点。
旁注:在Python中,我做了同样的事情:
j = defaultdict(int)
for k in clList:
j[k] +=1
result1 = max(j.iteritems(), key=lambda x:x[1]) //count of frequency of item with max count
答案 0 :(得分:14)
在您的问题与发布的其他答案之间存在很多替代方案,但其中许多似乎依赖于.get(0)
或.iterator().next()
会让您获得最频繁的观点元件。它不会!
你唯一的两个不错的选择是Multisets.copyHighestCountFirst(bag).elementSet().iterator().next()
,这就像你说的那样浪费,或者手动循环entrySet
并检查每一个是否是目前为止最常见的。
您应该提交Guava功能请求以提取最常用的元素。我不能保证会发生什么,但值得请求。
答案 1 :(得分:4)
一个不需要显式循环的替代解决方案 - 但是会在不同元素的数量中以线性时间运行,而其他大多数解决方案都不能 - 将是
Ordering.natural().onResultOf(new Function<Multiset.Entry<Foo>, Integer>() {
public Integer apply(Multiset.Entry<Foo> entry) {
return entry.getCount();
}
}.max(multiset.entrySet()).getElement();
答案 2 :(得分:2)
由于您的编辑和短语,您不清楚自己想要什么。另外,使用myList
作为多重集的变量名称不是描述性的 - 我将使用bag
作为multiset的变量名(毕竟它是包)。
“似乎Multiset已按照频率进行排序” - 它是否根据频率排序?
ImmutableMultiset<String> bag = ImmutableMultiset.of(
"c0ffee", "abba", "mfl", "mfl", "mfl", "c0ffee");
是[c0ffee x 2, abba, mfl x 3]
,因为它使用了广告订单,因此您的广告可能会按顺序正确排序(我不知道这是否属于这种情况)。如果您不确定订购,请使用
ImmutableMultiset<String> sortedBag = Multisets.copyHighestCountFirst(bag)
给出了[mfl x 3, c0ffee x 2, abba]
。由于Multisets.copyHighestCountFirst
返回不可变多重集,因此假设您的多重集不会更改,则不必在循环中使用它。如果你只是做了一个愚蠢的微基准测试并且看到使用Multisets.copyHighestCountFirst
的速度是80毫秒和40毫秒的两倍 - 请忘记它,因为premature optimization is the root of all evil。我认为此时我们已正确订购sortedBag
。
从我看到你想要的包中最常见元素的数量简单地说:
int count = sortedBag.entrySet().iterator().next().getCount();
或者您的多重集合是ImmutableMultiset
:
int count = sortedBag.entrySet().asList().get(0).getCount();
请注意,sortedBag.entrySet()
是Multiset.Entry
的集合,其中包含元素和计数,因此请选择一个。
让ImmutableMultiset
允许您使用ImmutableList
视图,您可以在其中调用get(0)
来获取元素:
sortedBag.asList().get(0)
只给你一个没有计数的元素(这里是一个字符串),所以如果你的计划是只获取元素,你可以使用asList()
而不是使用迭代器。
答案 3 :(得分:2)
今天我遇到了类似的挑战,试图找到一种简单,合理有效的方法来查找Multiset
中具有最大计数的元素。在未来我们生活在Java 8中,我能够将Louis Wasserman的solution修改成干净的一行:
multiset.entrySet().stream().max(Ordering.natural().onResultOf(Multiset.Entry::getCount)).get();
这将为Multiset.Entry
提供最大数量(假设multiset
不为空),允许您访问元素或其计数。