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;
}