Java - 将带有列表变量的对象转换为对象列表
Java - Turn Object with List Variable into a List of Objects
我的基本class是:
public class Student {
public String name;
public String className; // In real code I'd have a second object for return to the end user
public List<String> classes; // Can be zero
}
我想把它弄平,这样我就可以return像
[
{
"name":"joe",
"class":"science"
},
{
"name":"joe",
"class":"math"
},
]
为了简单起见,这显然是一个愚蠢的例子。
我能够做到的唯一方法是通过一些冗长的代码,例如:
List<Student> students = getStudents();
List<Student> outputStudents = new ArrayList<>();
students.forEach(student -> {
if(student.getClasses().size() > 0) {
student.getClasses().forEach(clazz -> {
outputStudents.add(new Student(student.getName(), clazz));
});
} else {
outputStudents.add(student);
}
});
看看有没有办法简化这个,也许使用 flapMap?
是的,您应该可以这样做:
Student student = ?
List<Student> output =
student
.getClasses()
.stream()
.map(clazz -> new Student(student.getName, student.getClassName, clazz))
.collect(Collectors.toList());
对于一个学生。对于一群学生来说,它有点复杂:
(根据@nullpointer 的评论进行了更新。谢谢!)
List<Student> listOfStudents = getStudents();
List<Student> outputStudents =
listOfStudents
.stream()
.flatMap(student -> {
List<String> classes = student.getClasses();
if (classes.isEmpty()) return ImmutableList.of(student).stream();
return classes.stream().map(clazz -> new Student(student.getName(), student.getClassName(), ImmutableList.of(clazz)));
})
.collect(Collectors.toList());
一种方法是根据 Student
中的 类 是否为空
的条件对当前列表进行分区
Map<Boolean, List<Student>> conditionalPartitioning = students.stream()
.collect(Collectors.partitioningBy(student -> student.getClasses().isEmpty(), Collectors.toList()));
然后进一步使用此分区 flatMap
到新学生列表,因为其中有 类 as 并且 concat
enate 他们与另一个分区最终收集到结果为:
List<Student> result = Stream.concat(
conditionalPartitioning.get(Boolean.FALSE).stream() // classes as a list
.flatMap(student -> student.getClasses() // flatmap based on each class
.stream().map(clazz -> new Student(student.getName(), clazz))),
conditionalPartitioning.get(Boolean.TRUE).stream()) // with classes.size = 0
.collect(Collectors.toList());
我的基本class是:
public class Student {
public String name;
public String className; // In real code I'd have a second object for return to the end user
public List<String> classes; // Can be zero
}
我想把它弄平,这样我就可以return像
[
{
"name":"joe",
"class":"science"
},
{
"name":"joe",
"class":"math"
},
]
为了简单起见,这显然是一个愚蠢的例子。
我能够做到的唯一方法是通过一些冗长的代码,例如:
List<Student> students = getStudents();
List<Student> outputStudents = new ArrayList<>();
students.forEach(student -> {
if(student.getClasses().size() > 0) {
student.getClasses().forEach(clazz -> {
outputStudents.add(new Student(student.getName(), clazz));
});
} else {
outputStudents.add(student);
}
});
看看有没有办法简化这个,也许使用 flapMap?
是的,您应该可以这样做:
Student student = ?
List<Student> output =
student
.getClasses()
.stream()
.map(clazz -> new Student(student.getName, student.getClassName, clazz))
.collect(Collectors.toList());
对于一个学生。对于一群学生来说,它有点复杂:
(根据@nullpointer 的评论进行了更新。谢谢!)
List<Student> listOfStudents = getStudents();
List<Student> outputStudents =
listOfStudents
.stream()
.flatMap(student -> {
List<String> classes = student.getClasses();
if (classes.isEmpty()) return ImmutableList.of(student).stream();
return classes.stream().map(clazz -> new Student(student.getName(), student.getClassName(), ImmutableList.of(clazz)));
})
.collect(Collectors.toList());
一种方法是根据 Student
中的 类 是否为空
Map<Boolean, List<Student>> conditionalPartitioning = students.stream()
.collect(Collectors.partitioningBy(student -> student.getClasses().isEmpty(), Collectors.toList()));
然后进一步使用此分区 flatMap
到新学生列表,因为其中有 类 as 并且 concat
enate 他们与另一个分区最终收集到结果为:
List<Student> result = Stream.concat(
conditionalPartitioning.get(Boolean.FALSE).stream() // classes as a list
.flatMap(student -> student.getClasses() // flatmap based on each class
.stream().map(clazz -> new Student(student.getName(), clazz))),
conditionalPartitioning.get(Boolean.TRUE).stream()) // with classes.size = 0
.collect(Collectors.toList());