Java Collectors: группировка списка объектов в список других объектов с вычисленными значениями - PullRequest
0 голосов
/ 09 декабря 2018

Я недавно получил в свои руки Java 8 и его Stream API, а недавно и его Collectors API, и я вижу, что у него есть потенциал для выполнения многих многих преобразований в поток, но у меня есть одна ситуация, когда я неуверен, если это возможно с Java 8 или даже возможно вообще.У меня есть два класса:

public class ClassA{
    public int group
    public int id
    public String title
    public String description
    public String keyword
    public String specialValue
}

public class ClassB{
    public String newTitle
    public String joinedDescriptions
}

Мне было интересно, можно ли сгенерировать из Списка объектов ClassA сгруппированный список объектов ClassB со значениями, рассчитанными из полей ClassA.Конкретно:

  • Группировка ClassA по комбинации группы и идентификатора
  • Сгруппированный экземпляр ClassB будет иметь newTitle = title, когда ключевое слово = 1, или newTitle = specialValue, когда ключевое слово = 2
  • И, наконец, joinDescription - это конкатенация всех описаний из сгруппированных экземпляров ClassA.

Я знаю, что возможно использование groupingBy группы Collectors для группировки экземпляров ClassA с использованием лямбда-выражения класса classA-> String.valueOf (classA.group) + String.valueOf (classA.id) или аналогичный, но я не знаю, как получить другие вычисленные значения для каждого сгруппированного экземпляра.

Я надеюсь, что это такобъяснил достаточно хорошо.

1 Ответ

0 голосов
/ 09 декабря 2018

ниже приведены шаги, которые необходимо предпринять;аналогично тому, что @Joakim Danielson упомянул в комментариях:

сгруппируйте список источников, как вы упомянули в своем посте, а затем добавьте конструктор в ClassB, который принимает список ClassA, а затем выполняетлогика, которую вы упомянули в терминах установки заголовка и объединения описаний:

, так что это будет ваш потоковый конвейер:

List<ClassB> result = source.stream()
                .collect(groupingBy(s -> s.getGroup() + "" + s.getId())) // Map<String, List<ClassA>>
                .values()  // Collection<List<ClassA>>
                .stream() // Stream<List<ClassA>>
                .map(ClassB::new) // Stream<ClassB>
                .collect(Collectors.toList()); //List<ClassB>>

, и вам понадобится конструктор в ClassB, определенный как:

public ClassB(List<ClassA> source) {
        ClassA item = source.get(0);
        if(“1”.equals(item.getKeyword())
             this.newtitle = item.getTitle();
        else if(“2”.equals(item.getKeyword())
             this.newtitle = “specialValue”; // or make a call to a method to compute the value
        this.joinedDescriptions = String.join(“, “, source.stream().map(ClassA::getDescription).collect(toList()));
}
...