在列表中查找前3个重现对象 - Java

时间:2018-05-07 12:25:33

标签: java list

处理项目,我需要能够找到列表中的前三个对象。

private List<Object> listOfObjects = new ArrayList<Object>();
listOfObjects.add(object1);
listOfObjects.add(object2);
listOfObjects.add(object2);
listOfObjects.add(object3);
listOfObjects.add(object3);
listOfObjects.add(object3);
listOfObjects.add(object4);

如何在此列表中显示前3个重现对象? 我正在寻找的结果是这样的。

Your top results are:
object3
object2
object1

3 个答案:

答案 0 :(得分:1)

如果您使用的是Java 8,则可以使用Collectors.groupingBy按出现次数对对象进行分组,如下所示:

Map<Object, Long> group = listOfObjects.stream()
        .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));

要获得前三名,您可以使用:

group.entrySet().stream()
        .sorted(Map.Entry.<Object, Long>comparingByValue().reversed())
        .limit(3) // here you can use a variable for the number of the top object you want
        .forEach(entry -> System.out.println(entry.getKey() + " = " + entry.getValue()));

你必须在Object类中@Override equals和hashcode方法。

我有一个简单的测试,我认为你的对象是一个字符串,例如:

List<Object> listOfObjects = new ArrayList<>();
listOfObjects.add("object1");
listOfObjects.add("object2");
listOfObjects.add("object2");
listOfObjects.add("object3");
listOfObjects.add("object3");
listOfObjects.add("object3");
listOfObjects.add("object4");

<强>输出

object3 = 3
object2 = 2
object1 = 1

答案 1 :(得分:1)

如果您愿意使用第三方库,Eclipse Collections有一个Collector可以将List转换为BagBag是一个无序的Collection,它允许重复项并在内部将项目映射到计数。它还有用于处理项目出现的特殊API。

List<ObjectIntPair<Object>> top3 =
        listOfObjects.stream()
                .collect(Collectors2.toBag())
                .topOccurrences(3);

此处的List(可能会令人惊讶地)有四个元素,因为object1object4将被视为对第三位有效。方法topOccurrences将由您决定如何处理存在关联的情况。

此代码也可以仅使用Eclipse Collections API实现。

MutableList<String> list = Lists.mutable.with(
        "object1",
        "object2", "object2",
        "object3", "object3", "object3",
        "object4");

MutableList<ObjectIntPair<String>> top3 = 
        list.countBy(each -> each).topOccurrences(3);

方法countBy采用Function,在这种情况下只是元素。还有一个Collectors2.countBy(Function)

注意:我是Eclipse Collections的提交者。

答案 2 :(得分:0)

我认为计算效率最高的方法之一(在列表上多次循环avoding),可能是创建另一个列表并迭代初始列表,将项目添加到新列表中,在添加每个项目之前,您可以询问新列表是否已包含对象:

    List<Object> newList = new ArrayList<>();
    for(Object o : listOfObjects) {
        if(newList.contains(o)) {
            System.out.println(o);
        } else {
            newList.add(o);
        }
    }