当前位置: 首页 > 知识库问答 >
问题:

Java8 Stream API:映射,分组通过到不同的对象

公良运锋
2023-03-14

我对Java8相当陌生。我需要将普通对象列表转换为按特定标准分组并在用户界面上显示。

  • 地图的关键应该是“fromDate-todate”的组合,学生名单应该与此组合相关联
  • 此外,“ClassOfMSWAN”对象需要转换为“Student”对象并保存到列表中
  • Java1的代码。7已编写,需要转换为Java1。八,

请帮帮我。

public class ClassOfMsSwan {

private String fromDate;
private String toDate;
private String studentName;
private String subject;
private String marks;

public ClassOfMsSwan(String fromDate, String toDate, String studentName, String subject, String marks) {
    super();
    this.fromDate = fromDate;
    this.toDate = toDate;
    this.studentName = studentName;
    this.subject = subject;
    this.marks = marks;
}
// setters and getters


public class Student {

private String name;
private String subject;
private String marks;
public Student(String name, String subject, String marks) {
    this.marks = marks;
    this.subject = subject;
    this.name = name;
}   
// setters and getters




List<ClassOfMsSwan> classes = new ArrayList<>();

    ClassOfMsSwan classOfMsSwan1 = new ClassOfMsSwan("06/01/2016", "05/31/2017", "David", "Physics", "98");
    ClassOfMsSwan classOfMsSwan2 = new ClassOfMsSwan("06/01/2016", "05/31/2017", "Jane", "Botany", "85");
    ClassOfMsSwan classOfMsSwan3 = new ClassOfMsSwan("06/01/2016", "05/31/2017", "Mathew", "Algebra", "76");

    ClassOfMsSwan classOfMsSwan4 = new ClassOfMsSwan("06/01/2017", "05/31/2018", "David", "Geometry", "94");
    ClassOfMsSwan classOfMsSwan5 = new ClassOfMsSwan("06/01/2017", "05/31/2018", "Jane", "Organic Chemistry", "92");
    ClassOfMsSwan classOfMsSwan6 = new ClassOfMsSwan("06/01/2017", "05/31/2018", "Mathew", "Botany", "100");

    ClassOfMsSwan classOfMsSwan7 = new ClassOfMsSwan("06/01/2018", "05/31/2019", "Mathew", "Geometry", "86");
    ClassOfMsSwan classOfMsSwan8 = new ClassOfMsSwan("06/01/2018", "05/31/2019", "Jane", "Algebra", "84");

    classes.add(classOfMsSwan1);
    classes.add(classOfMsSwan2);
    classes.add(classOfMsSwan3);
    classes.add(classOfMsSwan4);
    classes.add(classOfMsSwan5);
    classes.add(classOfMsSwan6);
    classes.add(classOfMsSwan7);
    classes.add(classOfMsSwan8);

    // JDK1.7
    Map<String, List<Student>> dateStudentMap = new HashMap<>();
    for(ClassOfMsSwan classOfMsSwan : classes) {
        List<Student> students = dateStudentMap.get(classOfMsSwan.getFromDate() + "-" + classOfMsSwan.getToDate());
        if(CollectionUtils.isEmpty(students)) {
            students = new ArrayList<>();
            dateStudentMap.put(classOfMsSwan.getFromDate() + "-" + classOfMsSwan.getToDate(), students);
        }
        students.add(new Student(classOfMsSwan.getStudentName(), classOfMsSwan.getSubject(), classOfMsSwan.getMarks()));
    }


Desired output
   {06/01/2016-05/31/2017=[Student [name=David, subject=Physics, marks=98], Student [name=Jane, subject=Botany, marks=85], Student [name=Mathew, subject=Algebra, marks=76]], 06/01/2017-05/31/2018=[Student [name=David, subject=Geometry, marks=94], Student [name=Jane, subject=Organic Chemistry, marks=92], Student [name=Mathew, subject=Botany, marks=100]], 06/01/2018-05/31/2019=[Student [name=Mathew, subject=Geometry, marks=86], Student [name=Jane, subject=Algebra, marks=84]]}

共有1个答案

谭昱
2023-03-14

您可以通过如下方式使用Java 8 API实现此目的:

Map<String, Set<Student>> dateStudentMap = classes.stream().map(e ->  
                new Entry(e.getFromDate() + "-" + e.getToDate(),
                        new Student(e.getStudentName(), e.getSubject(), e.getMarks())
            ))
    .collect(groupingBy(Entry::getKey, TreeMap::new,
            mapping(Entry::getValue, toSet())));

其中,我使用一个基本的助手类条目定义如下:

class Entry{
    public Entry(String key, Student value){
        this.setKey(key);
        this.setValue(value);
    }
    //getters and setters

    private String key;
    private Student value;
}

希望有帮助。

编辑:

根据霍尔格的评论(好得多):

    Map<String, Set<Student>> dateStudentMap8 = classes.stream()
            .collect(groupingBy(e -> 
                        e.getFromDate() + "-" + e.getToDate(),
                        mapping(e -> 
                            new Student(e.getStudentName(), 
                                        e.getSubject(), 
                                        e.getMarks()), 
                            toSet())));

 类似资料:
  • 通过聚合和分组将一个对象映射到另一个对象 ToQ的输出应为 我尝试使用分组函数,但它生成了HashMap但不确定如何转换为对象。

  • 我正在从React中的外部api接收数据 我有一个目标 我试图通过它进行映射,以便能够渲染数据,即它在屏幕上显示的“bitfinex:1.2、blockfi:2.3等” 但是我得到了一个错误,说它不是一个函数。 我做错了什么?

  • 我有一个对象数组,我想迭代它来生成一个新的过滤数组。但是,我还需要根据参数从新数组中筛选出一些对象。我正在尝试: 这是一个好的方法吗?有更好的方法吗?我愿意使用任何库,比如洛达什。

  • 我正在尝试将我的对象[]数组映射并过滤到int[]数组。如果对象是int,效果很好,但如果不是int,则抛出强制转换异常。我想知道我是否可以在lambda表达式中附加一个try/catch?这是我的代码: 或者更好的方法是试着抓住整个街区?

  • 流上的操作是否可以生成一个映射,其中值是数组而不是列表或其他集合类型? 例如:我有一个类。事物有所有者,所以有一个方法。在一个事物流中,我想按所有者ID对事物进行分组,以便具有相同所有者ID的事物最终在一个数组中。换句话说,我想要一个像下面这样的映射,其中键是所有者ID,值是属于该所有者的事物数组。 在我的例子中,因为我需要将映射值传递给一个需要数组的库方法,所以收集到一个< code >映射中是

  • 使用一个函数将数组的值映射到对象,其键值对中,原始值作为键,映射值作为值。 使用一个匿名的内部函数作用域来声明一个 undefined 的内存空间,使用闭包来存储返回值。 使用一个新的 Array 来存储带有函数映射的数组和一个逗号运算符来返回第二个步骤,而不需要从一个上下文移动到另一个上下文(由于闭包和操作顺序)。 const mapObject = (arr, fn) => (a => (