有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

在Java列表中查找前3个重复出现的对象

在一个项目中工作,我需要能够找到列表中的前三个对象

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) 个答案

  1. # 1 楼答案

    如果您愿意使用第三方库,Eclipse Collections有一个Collector,它可以将List转换为BagBag是一个无序的{},它允许重复项,并在内部将项映射到计数。它还具有用于处理项目发生情况的特殊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集合的提交者

  2. # 2 楼答案

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

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

    如果您使用的是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()));
    

    必须@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