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

前端 未结 5 1452
伪装坚强ぢ
伪装坚强ぢ 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

    It's still pretty ugly, and I think it would be improved by changing how you model things a bit, but I've only managed to come up with the following so far:

    public static void main(String[] args) {
        Person[] people = {new Person("00001"), new Person("00002"), new Person("00005")};
        Region[] regions = {
                new Region("Region 1", Arrays.asList("00001", "00002", "00003")),
                new Region("Region 2", Arrays.asList("00002", "00003", "00004")),
                new Region("Region 3", Arrays.asList("00001", "00002", "00005"))
        };
    
        Map> result = Stream.of(regions)
                .flatMap(region -> region.getZipCodes().stream()
                        .map(zip -> new SimpleEntry<>(zip, region)))
                .flatMap(entry -> Stream.of(people)
                        .filter(person -> person.getZip().equals(entry.getKey()))
                        .map(person -> new SimpleEntry<>(person, entry.getValue())))
                .collect(Collectors.groupingBy(Entry::getKey, Collectors.mapping(Entry::getValue, Collectors.toList())));
    
        result.entrySet().forEach(entry -> System.out.printf("[%s]: {%s}\n", entry.getKey(), entry.getValue()));
    
        //      Output:
        //      [Person: 0]: {[name: Region 1, name: Region 3]}
        //      [Person: 1]: {[name: Region 1, name: Region 2, name: Region 3]}
        //      [Person: 2]: {[name: Region 3]}
    }
    

    Having a ZipCode class that contained the mapping and could be keyed on would make things cleaner:

    public static void main(String[] args) {
            Region r1 = new Region("Region 1");
            Region r2 = new Region("Region 2");
            Region r3 = new Region("Region 3");
    
            ZipCode zipCode1 = new ZipCode("00001", Arrays.asList(r1, r3));
            ZipCode zipCode2 = new ZipCode("00002", Arrays.asList(r1, r2, r3));
            ZipCode zipCode3 = new ZipCode("00003", Arrays.asList());
            ZipCode zipCode4 = new ZipCode("00004", Arrays.asList());
            ZipCode zipCode5 = new ZipCode("00005", Arrays.asList(r3));
    
            Person[] people = {
                    new Person(zipCode1),
                    new Person(zipCode2),
                    new Person(zipCode5)
            };
    
            Map> result = Stream.of(people)
                .collect(Collectors.toMap(person -> person,
                        person -> person.getZip().getRegions()));
    
            result.entrySet().forEach(entry -> System.out.printf("[%s]: {%s}\n", entry.getKey(), entry.getValue()));
    
    //      Output:
    //      [Person: 0]: {[name: Region 1, name: Region 3]}
    //      [Person: 1]: {[name: Region 1, name: Region 2, name: Region 3]}
    //      [Person: 2]: {[name: Region 3]}
    }
    

提交回复
热议问题