Записать два для инструкций в виде потока

#java #stream

#java #поток

Вопрос:

У меня есть два списка Pearson (переменных: FirstName , LastName , AllFirstName ). Один из них содержит дубликаты (если у pearson есть два первых имени, то в этом списке будет по две записи для каждого имени, но фамилия будет одинаковой), а один из них имеет только уникальные значения (listWithUniquePearsons). Второй список будет создан путем перебора первого списка и помещения всех первых имен в список объектов. Я написал это с помощью two for . Есть ли какой-нибудь способ записать его как a stream ?

 for (Pearson prs : listWithUniquePearsons) {
    List<String> firstNames = new ArrayList<String>();
    for (Pearson tempPerson : allPearsons) {
        if (prs.getLastName().equals(tempPerson.getLastName())) {
            firstNames.add(tempPerson.firstNames());
        }
    }

    if (firstNames.size()>1) {
        prs.setAllFirstNames(firstNames);
    }
}
  

Комментарии:

1. AllFirstName это список строк?

2. не могли бы вы показать нам свою модель, пожалуйста?

3. Да, это список строк.

Ответ №1:

 List<String> firstNames = listWithUniquePearsons
        .stream()
        .map(prs -> allPearsons.stream()
                               .filter(tempPerson -> prs.getLastName().equals(tempPerson.getLastName()))
                               .map(Person::getFirstName)
                               .collect(Collectors.toList());
  

Комментарии:

1. Этот код поврежден и не компилируется, первая map операция не завершена. Вы имели в виду использовать flatMap ?

Ответ №2:

Вы должны создать карту с ключом lastName и значениями List<FirstName> , а затем переназначить ее записи обратно в настройку класса Pearson allFirstNames . Это можно сделать с помощью потоков и коллекторов Java 8.

Давайте предположим, что класс Pearson реализован следующим образом:

 import java.util.*;

public class Pearson {
    private String firstName;
    private String lastName;
    private List<String> allFirstNames;
        
    public Pearson(String first, String last) {
        this.firstName = first;
        this.lastName = last;
    }
        
    public Pearson(List<String> allFirst, String last) {
        this.allFirstNames = allFirst;
        this.lastName = last;
    }
        
    public String getFirstName() {return firstName; }
    public String getLastName() {return lastName; }
    public List<String> getAllFirstNames() {return allFirstNames; }
}
  

Тестовый код:

 import java.util.*;
import java.util.stream.*;

public class Test {
    public static void main(String[] args) {
        List<Pearson> duplicates = Arrays.asList(
            new Pearson("John", "Doe"),
            new Pearson("William", "Doe"),
            new Pearson("Edgar", "Poe"),
            new Pearson("Allan", "Poe"),
            new Pearson("Don", "King")
        );
        List<Pearson> uniques = duplicates.stream()
                                          // map LastName -> List<FirstName>
                                          .collect(Collectors.groupingBy(
                                              Pearson::getLastName,
                                              LinkedHashMap::new, // keep order of entries
                                              Collectors.mapping(
                                                  Pearson::getFirstName,
                                                  Collectors.toList())
                                          )).entrySet()
                                          .stream()
                                          .map(e -> new Pearson(e.getValue(), e.getKey()))
                                          .collect(Collectors.toList());
        
        uniques.forEach(u -> 
            System.out.println(
                String.join(" ", u.getAllFirstNames()) 
                  " "   u.getLastName()
        ));   
    }
}
  

Вывод

 John William Doe
Edgar Allan Poe
Don King