如何在给定对象列表的情况下找到前 N 个?
How to find Top N given a list of Object?
我想在映射中存储键值对 并按照以下逻辑根据键的值(数据列表)对条目进行排序:
- 按数据对象中的分数对每个键(组)的值(在列表中)进行排序,并且
- 如果地图的大小大于 n(比如 n = 3)- 然后根据第一个项目的(值)分数和 return 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)
我想在映射中存储键值对
- 按数据对象中的分数对每个键(组)的值(在列表中)进行排序,并且
- 如果地图的大小大于 n(比如 n = 3)- 然后根据第一个项目的(值)分数和 return 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)