Java-将具有列表变量的对象转换为对象列表

时间:2019-01-17 20:31:52

标签: java arrays java-stream flatmap

我的基础课是:

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
}

我想把它弄平,这样我就可以返回类似的东西

[
  {
    "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);
  }
});

查看是否有一种方法可以简化此过程,例如可以使用flipMap吗?

2 个答案:

答案 0 :(得分:1)

是的,您应该可以执行以下操作:

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());

答案 1 :(得分:1)

一种方法是,根据条件Student中的类是否为空来对Map<Boolean, List<Student>> conditionalPartitioning = students.stream() .collect(Collectors.partitioningBy(student -> student.getClasses().isEmpty(), Collectors.toList())); 的当前列表进行分区

flatMap

然后进一步将该分区用于concat到新学生的列表中,前提是这些学生中有班级,并且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()); 用另一个分区对其进行充实,最终将其收集为:

const cmsData = [{..},{..},{..},{..}]
const arr = [...firstItems, last] = cmsData