class Person{
    private String first;
    private String last;
    private BigDecimal gpa;
    private int age;
}

class PersonKey{
    private String first;
    private String last;
}

Teraz mam List<Person> i chcesz przekonwertować to do Map<PersonKey, Person> gdzie PersonKey jest tylko unikalną wartością kluczową osobą. Jak mogę to osiągnąć dzięki strumieniowi Java?

-2
jconnie87 16 kwiecień 2021, 02:07

3 odpowiedzi

Najlepsza odpowiedź

Wierzę, że właśnie szukasz (zakładanie dwóch osób ma taką samą nazwę). Klucz jest zbudowany w locie przy użyciu getters z osoby i konstruktora z personelu.

Map<PersonKey, Person> map = list.stream()
       .collect(Collectors.toMap(
                 person->new PersonKey(person.getFirst(),person.getLast()), 
                 person->person));

Aby pomieścić ludzi o tej samej nazwie, możesz umieścić je w Map<PersonKey,List<Person>>

Map<PersonKey, List<Person>> map = list.stream()
              .collect(Collectors.groupingBy(person->new 
                              PersonKey(person.getFirst(),
                                        person.getLast())));
2
WJS 16 kwiecień 2021, 02:13

Możesz uważać, aby oglądać dla duplikatów kluczy. Jeśli klucze są duplikatem, wtedy zostanie rzucony nielegalneStateException.

Wypróbuj to dla duplikatów kluczy zamiast tego:

// Map<PersonKey, Person> mapThrowException = list.stream().collect(
//      Collectors.toMap(p -> new PersonKey(p.first, p.last), p -> p));

// for duplicate keys, choose the first one
Map<PersonKey, Person> properMap = list.stream().collect(
        Collectors.toMap(p -> new PersonKey(p.first, p.last), p -> p,  (person1, person2) -> person1 ));
1
Khanna111 16 kwiecień 2021, 00:44

Zrobić klasę

Pozostałe dwie odpowiedzi są poprawne, Oto & amp; Oto.

Ale jeśli używasz pełnej nazwy osoby w ten sposób, rozważ pisanie klasy. Jeśli używasz pełnego imienia w innych miejscach, a następnie więcej powodów, aby stworzyć klasę.

W Javie 16, a później możesz użyć nowej Rekord Funkcja, aby bardziej skrócić klasa. Użyj rekordu, w którym głównym celem jest komunikowanie danych, przejrzystych i niezmiennie. Kompilator niejawnie tworzy konstruktor, gettery, equals & amp; hashCode i toString.

record FullName ( String firstName , String lastName ) {}

Więc klasa Person wyglądałaby tak.

class Person{
    private FullName name;
    private BigDecimal gpa;
    private int age;
}

Przykład użycia.

Person p = new Person ( 
    new FullName( "Alice" , "Alba" ) , 
    new BigDecimal( "3.67" ) , 
    23 
) ;

A twoja mapa wyglądałaby tak.

Map< FullName , Person > map = … 

Nawiasem mówiąc, przy użyciu nazwy osoby jako identyfikatora jest prawie zawsze straszny pomysł w praktyce. Dlatego uczniowie są przypisani numery identyfikatorów studentów, pracownicy otrzymują identyfikatory pracowników, paszporty otrzymują oficjalny numer paszportu i tak dalej. Ignorowałem ten problem w odpowiedzi, aby skupić się na innych kwestiach ... ale być uprzedzony.

1
Basil Bourque 16 kwiecień 2021, 01:25