简体   繁体   English

如何对列表中两个不同类的字段进行排序?

[英]How to sort fields from two different classes in a list?

I have the below code where I need to sort the list based on fields from different classes.我有下面的代码,我需要根据来自不同类的字段对列表进行排序。

Is it possible to sort data on fields from different classes and make it into one list?是否可以对来自不同类别的字段的数据进行排序并将其整合到一个列表中?

import java.util.*;
import java.util.stream.Collectors;

public class Sample4 {

    private class Student {
        String name;
        Set<Marks> marks;

    }

    private class Marks {
        double points;
    }

    public static void main(String[] args) {
        System.out.println(new Sample4().test());
    }

    public List<Marks> test() {
        Set<Marks> marks = new LinkedHashSet<>(), marks1 = new LinkedHashSet<>(), marks2 = new LinkedHashSet<>();
        marks.add(new Marks(10.2));
        marks.add(new Marks(2.10));
        marks1.add(new Marks(20));
        marks1.add(new Marks(7));
        marks2.add(new Marks(13));
        marks2.add(new Marks(15));

        List<Student> stds = Arrays.asList(
                new Student("A", marks),
                new Student("C", marks1),
                new Student("B", marks2)
        );

        return stds.stream().sorted(Comparator.comparing(Student::getName)).flatMap(std -> std.getMarks().stream()).sorted(Comparator.comparing(Marks::getPoints)).collect(Collectors.toList());
    }
}

Please find the code above for reference.请找到上面的代码以供参考。 But the output I'm looking for is as below:但我正在寻找的输出如下:

A -> 2.10, 10.2 A -> 2.10、10.2

B -> 13, 15乙 -> 13, 15

C -> 7, 20 C -> 7, 20

If you want an output consisted of a link between a student name A and the marks such as 2.10 and 10.2 , then you need either the Map<String, List<Mark>> output or use the current List<Student that is just sorted as you need:如果您希望输出由学生姓名A与标记(例如2.1010.2之间的链接组成,则您需要Map<String, List<Mark>>输出或使用刚刚排序为的当前List<Student你需要:

The output is List<Student> :输出是List<Student>

return stds.stream()
  .sorted(Comparator.comparing(Student::getName))              // sort Students by name
  .map(student -> new Student(                                 // with sorted marks
     student.getName(),                                        // - same name
     student.getMarks().stream()                               // - sorted marks
       .sorted(Comparator.comparingDouble(Marks::getPoints))   // -- comparing points
       .collect(Collectors.toCollection(LinkedHashSet::new)))) // -- as LinkedHashSet
  .collect(Collectors.toList());                               // as List<Student>

[Student(name=A, marks=[Marks(points=2.1), Marks(points=10.2)]), [学生(姓名=A,分数=[分数(分数=2.1),分数(分数=10.2)]),

Student(name=B, marks=[Fooarks(points=13.0), Marks(points=15.0)]),学生(姓名=B, 分数=[Fooarks(points=13.0), Marks(points=15.0)]),

Student(name=C, marks=[Marks(points=7.0), Marks(points=20.0)])]学生(姓名=C,分数=[分数(分数=7.0),分数(分数=20.0)])]


If you find Map<String, List<Mark>> somehow more appropriate, then mind the TreeMap implementation that sorts the keys:如果您发现Map<String, List<Mark>>更合适,那么请注意对键进行排序的TreeMap实现:

return stds.stream()
    .collect(Collectors.toMap(                           // Map<String, List>
         Student::getName,                               // the key
         student -> student.getMarks().stream()          // the value (sorted)
             .sorted(Comparator.comparingDouble(
                     Marks::getPoints))
             .collect(Collectors.toList()),
         (o1, o2) -> o1,                                 // merge BinaryOperator
         TreeMap::new));                                 // requested implementation

{A=[Foo.Marks(points=2.1), Foo.Marks(points=10.2)], {A=[Foo.Marks(points=2.1), Foo.Marks(points=10.2)],

B=[Foo.Marks(points=13.0), Foo.Marks(points=15.0)], B=[Foo.Marks(points=13.0), Foo.Marks(points=15.0)],

C=[Foo.Marks(points=7.0), Foo.Marks(points=20.0)]} C=[Foo.Marks(points=7.0), Foo.Marks(points=20.0)]}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM