如何在给定对象列表的情况下找到前 N 个?

How to find Top N given a list of Object?

我想在映射中存储键值对 并按照以下逻辑根据键的值(数据列表)对条目进行排序:

  1. 按数据对象中的分数对每个键(组)的值(在列表中)进行排序,并且
  2. 如果地图的大小大于 n(比如 n = 3)- 然后根据第一个项目的(值)分数和 return 3 对键(组)进行排序。 - 相当于说得到根据高分
  3. 前3名(每组1名)

我希望每组获得 1 个结果 (A,B,C,D)

 import java.util.ArrayList; 

public class MyClass {

    public static void main(String args[]) {
      
       // output should be just Data(17.0, "five", "D"), Data(4.0, "two", "A"), Data(3.0, "three", "B")
      ArrayList<Data> dataList = new ArrayList<Data>();
        dataList.add(new Data(1.0, "one", "A"));
        dataList.add(new Data(4.0, "two", "A"));
        dataList.add(new Data(3.0, "three", "B"));
        dataList.add(new Data(2.0, "four", "C"));
        dataList.add(new Data(7.0, "five", "D"));
        dataList.add(new Data(17.0, "five", "D"));
        
// output should be just Data(5.0, "six", "A"), Data(3.14, "two", "B"), Data(3.14, "three", "C")
      ArrayList<Data> dataList2 = new ArrayList<Data>();
        dataList2.add(new Data(3.0, "one", "A"));
        dataList2.add(new Data(5.0, "six", "A"));
        dataList2.add(new Data(3.14, "two", "B"));
        dataList2.add(new Data(3.14, "three", "C"));
        
      System.out.println("data 1=  " + dataList.size());
      System.out.println("data 2 =  " + dataList2.size());

    }
    
  static class Data {
     double score;
     String name; 
     String group;
     
      
    public Data(double score, String name, String group) {
        score = this.score;
        name = this.name;
        group = this.group;
    }
    
    public String getName() {
        return name;
    }
     
    public String getGroup() {
        return group;
    }
    
    public double getScore() {
        return score;
    }
    }
}

我知道执行此操作的程序方法,但在 Java 8 中有 smarter/functional 方法吗?

I am looking get 1 result per group (A,B,C,D)

I want to store key-value pairs <String, List>

不知何故相互矛盾。但我假设您希望获得每个组中得分最高的条目,并将结果限制为某个给定大小 n。如果这是真的,请尝试像下面这样的方法来获得一个地图,其中前 n 个元素以 group 作为键,而 Data 对象本身作为值

long n = 3;

Map<String,Data> result =
            dataList.stream()
            .collect(Collectors.groupingBy(Data::getGroup,
                    Collectors.collectingAndThen(Collectors.maxBy(Comparator.comparingDouble(Data::getScore)),
                            Optional::get)))
            .entrySet()
            .stream()
                    .sorted(Comparator.comparing(e -> e.getValue().getScore(),Comparator.reverseOrder()))
                    .limit(n)
                    .collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue,(a,b) -> a, LinkedHashMap::new));

result.entrySet().forEach(System.out::println);

获得

D=MyClass.Data(score=17.0, name=five, group=D)
A=MyClass.Data(score=4.0, name=two, group=A)
B=MyClass.Data(score=3.0, name=three, group=B)

或者,如果您只需要列表的子列表,其中包含每个组中的最大分数元素(因为组值在对象本身中可用),则执行如下操作:

List<Data> result =
            dataList.stream()
            .collect(Collectors.groupingBy(Data::getGroup,
                    Collectors.collectingAndThen(Collectors.maxBy(Comparator.comparingDouble(Data::getScore)),
                            Optional::get)))
            .values()
            .stream()
                    .sorted(Comparator.comparingDouble(Data::getScore).reversed())
                    .limit(n)
                    .collect(Collectors.toList());
    result.forEach(System.out::println);

result.forEach(System.out::println);

获得

MyClass.Data(score=17.0, name=five, group=D)
MyClass.Data(score=4.0, name=two, group=A)
MyClass.Data(score=3.0, name=three, group=B)