JAVA8:将原始数据列表转换为键映射和计算值列表

JAVA8:将原始数据列表转换为键映射和计算值列表,java,java-8,Java,Java 8,我有一个原始学生数据列表,如下所述 [ { section : 1A branch : science studentName : abc marks : 50 }, { section : 1A branch : science studentName : sss marks : 20 }, { section : 1A branch : science stud

我有一个原始学生数据列表,如下所述

  [
    {
    section : 1A
    branch : science
    studentName : abc
    marks : 50
    },
    {
    section : 1A
    branch : science
    studentName : sss
    marks : 20
    },
    {
    section : 1A
    branch : science
    studentName : asd
    marks : 40
    },
    {
    section : 1A
    branch : Maths
    studentName : www
    marks : 10
    },
    {
    section : 1A
    branch : Maths
    studentName : abc
    marks : 70
    },
    {
    section : 1A
    branch : Maths
    studentName : abc
    marks : 86
    },
    {
    section : 2A
    branch : Maths
    studentName : abc
    marks : 55
    },
    {
    section : 2A
    branch : Maths
    studentName : abc
    marks : 89
    },
    {
    section : 2A
    branch : Maths
    studentName : abc
    marks :12
    },
  {
    section : 2A
    branch : physical
    studentName : abc
    marks :passed
    },
  {
    section : 2A
    branch : physical
    studentName : abc
    marks :failed
    },
    ]
现在,我想将这些数据转换成以下格式:我想为特定科目的所有学生获得最低分数和最高分数。我想在所有部分都这样做。基本上,我想看看所有部分中所有主题的最小和最大分数是多少

我还有一个科目“物理测试”,价值观是及格还是不及格。我想知道有多少是失败的,包括上述细节。现在我必须将这个变量声明为字符串,因为我可能包含实际的标记或通过/失败。你有什么建议吗

section 1A:
science : 20-50(min-max)
math : (10-86)(min-max)
section 2S:
science : 20-50(min-max)
math : (12-89)(min-max)
我能够使用下面的代码将sec映射到学生列表

Map<String, List<Student>> map2 = studentsList.stream().collect(Collectors
                    .groupingBy(Student::getSection, HashMap::new, Collectors.toCollection(ArrayList::new)));
Map map2=studentsList.stream().collect(收集器
.groupingBy(Student::getSection,HashMap::new,Collectors.toCollection(ArrayList::new));
我正在从源系统接收通过/失败的值,我无法更改该值。我已将该变量定义为字符串,因为它可能包含整数或字符串标记(通过/失败)。我一直在尝试使用流编写干净的代码,避免过多的循环和if语句,但我无法做到这一点。如果受试者有分数,则将其分组为最小-最大值,如果受试者通过/失败的值大于noOfFailed_totalstudents。

我无法使用java流来完成它。请帮忙。我也在尝试,如果完成了,将进行更新。

这是我最好的尝试。学生的班级不是很干净。最好使用两个不同的类为分数相关科目和失败/通过相关科目建模,并使用工厂,但无论如何:

@Data
public static class Student implements Comparable<Student>{
    private String section;
    private String branch;
    private String studentName;
    private String marks;
    private Integer points;

    public Student(String section, String branch, String studentName, String marks) {
        this.section = section;
        this.branch = branch;
        this.studentName = studentName;
        try {
            this.points = Integer.valueOf(marks);
        } catch (Exception e) {
            this.marks = marks;
        }
    }

    @Override
    public int compareTo(Student o) {
        if (o != null){
           if (this.getPoints() != null && o.getPoints() != null){
               return this.getPoints() - o.getPoints();
           } else if (this.getMarks() != null && o.getMarks() != null){
               if (this.getMarks().equalsIgnoreCase(o.getMarks())){
                   return 0;
               } else if (this.getMarks().equals("passed")){
                   return 1;
               } else {
                   return -1;
               }
           }
        }
        return 1;
    }

实际上,通过流API一步一步地完成这项工作是很困难的。它分几个步骤进行。 我假设您有一个json字符串,并将其转换为
Student
对象数组

步骤1:将json字符串转换为对象:

class Student {
    private String section;
    private String branch;
    private String studentName;
    private Object marks;
}  
“学生姓名”是“学生姓名”的,”学生姓名是“学生姓名”的,”,”学生姓名是“学生姓名”的。“abc\”,“标记”50},,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,:\“www\,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,“:\'abc\',\'marks\':89},{“section\”:“2A\”,“branch\”:“Math\”,“studentName\”:“abc\”,“marks\”:12},{“section\”:“2A\”,“branch\”:“physical\”,“studentName\”:“abc\”,“marks\”:“failed\”,{“section\”:“2A\”,“,“branch\”:“physical\”,“studentName\”:“abc\”,“passed\”;“Mark\”:“code\”;“>

步骤2:按
节和分支属性分组

Map<String, Map<String, List<Object>>> map = 
Arrays.stream(objectMapper.readValue(jsonData, Student[].class))
            .collect(Collectors.groupingBy(Student::getSection,
                    Collectors.groupingBy(Student::getBranch,
                            Collectors.mapping(Student::getMarks, Collectors.toList()))));


如何表示最小值和最大值?只是
20-50
没有任何意义。请参考此内容并首先发布最小值和可复制的样本:Hi Ravindra,20和50是该部分特定主题的最小值和最大值标记。您将如何存储它们?以字符串形式。基本上我得到的是原始数据流。我正在对此进行评估将原始数据存入JSON并保存在我的文件中。我把分数作为主题:MIN Max在节的基础上保存,所以我将有主题的MIN Max标记的细节。代替标记,我也可以作为NofFassSuthStaseNoSs作为物理测试存储。d通过?您好,我使用了类似的方法,您不需要comparable,而是使用statistics类查找最小值和最大值。我们可以使用正则表达式检查值是否为整数或字符串。上述表达式方法不正确。
Section 1A: math: 12-89(min-max)
Section 1A: physics: 2-3(failed-total)
class Student {
    private String section;
    private String branch;
    private String studentName;
    private Object marks;
}  
ObjectMapper objectMapper = new ObjectMapper();
Map<String, Map<String, List<Object>>> map = 
Arrays.stream(objectMapper.readValue(jsonData, Student[].class))
            .collect(Collectors.groupingBy(Student::getSection,
                    Collectors.groupingBy(Student::getBranch,
                            Collectors.mapping(Student::getMarks, Collectors.toList()))));
List<Statistics> result = map.entrySet().stream()
            .map(Statistics::new)
            .collect(Collectors.toList());
class Statistics {
  private String section;
  private MinMax science;
  private MinMax maths;
  private long totalFailed;

  public Statistics(Map.Entry<String, Map<String, List<Object>>> entry) {
     this.section = entry.getKey();
     IntSummaryStatistics maths = entry.getValue().getOrDefault("Maths",emptyList())
            .stream()
            .map(o -> Integer.valueOf(o.toString()))
            .collect(Collectors.summarizingInt(value -> value));
     this.maths = new MinMax(maths.getMin(), maths.getMax());

     IntSummaryStatistics science = entry.getValue().getOrDefault("science",emptyList())
            .stream()
            .map(o -> Integer.valueOf(o.toString()))
            .collect(Collectors.summarizingInt(value -> value));
     this.science = new MinMax(science.getMin(), science.getMax());

     this.totalFailed = entry.getValue()
         .getOrDefault("physical",emptyList())
         .stream()
         .filter(o -> o.toString().equals("failed"))
         .count();
  }
}
class MinMax {
  private Integer min;
  private Integer max;
}