How to group elements of a List by elements of another in Java 8

前端 未结 5 1543
伪装坚强ぢ
伪装坚强ぢ 2021-02-16 00:09

I have the following problem: Given these classes,

class Person {
    private String zip;
    ...
    public String getZip(){
        return zip;
    }
}

class          


        
5条回答
  •  一整个雨季
    2021-02-16 00:46

    The original answer does an unnecessary mapping with tuples, so you see there the final solution. You could remove the mapping, and simply filter directly the regions list:

    //A Set is more appropriate, IMO
    .stream()
    .collect(toMap(p -> p, 
                   p -> regions.stream()
                               .filter(r -> r.getZipCodes().contains(p.getZip()))
                               .collect(toSet())));
    


    If I understand well, you could do something like this:

    import java.util.AbstractMap.SimpleEntry;
    import static java.util.stream.Collectors.toMap;
    import static java.util.stream.Collectors.toList;
    
    ...
    
    List persons = ...;
    List regions = ...;
    
    Map> map = 
        persons.stream()
               .map(p -> new SimpleEntry<>(p, regions))
               .collect(toMap(SimpleEntry::getKey, 
                              e -> e.getValue().stream()
                                               .filter(r -> r.getZipCodes().contains(e.getKey().getZip()))
                                               .collect(toList())));
    

    From the List you get a Stream. Then you map each instance to a tuple > that contains all the regions. From there, you collect the data in a map with the toMap collector and, for each person, you build a List of Region that contains the zip code of that person.

    For example, given the input:

    List persons = Arrays.asList(new Person("A"), new Person("B"), new Person("C"));
    
    List regions = 
         Arrays.asList(new Region(Arrays.asList("A", "B")), new Region(Arrays.asList("A")));
    

    It outputs:

    Person{zip='A'} => [Region{zipCodes=[A, B]}, Region{zipCodes=[A]}]
    Person{zip='B'} => [Region{zipCodes=[A, B]}]
    Person{zip='C'} => []
    

    Also I guess the zipCodes for each Region could be a Set.

提交回复
热议问题