Java - превращение объекта со списочной переменной в список объектов - PullRequest
0 голосов
/ 17 января 2019

Мой базовый класс:

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

Ищете способ упростить это, возможно, используя flapMap?

Ответы [ 2 ]

0 голосов
/ 18 января 2019

Один из способов сделать это - разделить текущий список 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());
0 голосов
/ 17 января 2019

Да, вы должны быть в состоянии сделать что-то вроде этого:

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