多行Java流收集抛出

时间:2017-01-04 19:44:39

标签: java java-8 java-stream

我有两种类型:

@Data
public class SomePersonType {

    private String name;

    private int age;
}

@Data
@Builder
public class SomeOtherPersonType {

    private String name;

    private int age;
}

我需要将一种类型的地图转换为另一种类型的地图。所以,我的代码看起来像这样:

public class Main {

    public static void main(final String... args) {
        final Map<String, SomePersonType> somePersonTypeMap = new HashMap<>();

        // ...
        // populating the map above with some values
        // ...

        final Map<String, SomeOtherPersonType> someOtherPersonTypeMap = somePersonTypeMap.entrySet().stream()
                .collect(Collectors.toMap(
                        Map.Entry::getKey,
                        entry -> SomeOtherPersonType.builder()
                                    .name(entry.getValue().getName())
                                    .age(entry.getValue().getAge())
                                    .build()
                ));
    }
}

我的真实代码包含许多其他属性。所以,我不想多次entry.getValue()。我想把它放在一个局部变量然后使用它。像这样:

public class Main {

    public static void main(final String... args) {
        final Map<String, SomePersonType> somePersonTypeMap = new HashMap<>();

        // ...
        // populating the map above with some values
        // ...

        final Map<String, SomeOtherPersonType> someOtherPersonTypeMap = somePersonTypeMap.entrySet().stream()
                .collect(Collectors.toMap(
                        Map.Entry::getKey,
                        entry -> {
                            final SomePersonType somePersonType = entry.getValue();
                            SomeOtherPersonType.builder()
                                    .name(somePersonType.getName())
                                    .age(somePersonType.getAge())
                                    .build();
                        }
                ));
    }
}

但是我遇到两个编译器错误:

Map.Entry::getKey - &gt; Non-static method cannot be referenced from a static contextentry.getValue() - &gt; Cannot resolve method 'getValue()'

有人可以指出我做错了什么吗?感谢。

1 个答案:

答案 0 :(得分:2)

就lambda表达式而言,final语句应返回一个值,以便映射Function的值返回映射值:

Map<String, SomeOtherPersonType> someOtherPersonTypeMap = somePersonTypeMap.entrySet()
            .stream()
            .collect(Collectors.toMap(
                    Map.Entry::getKey,
                    entry -> {
                        final SomePersonType somePersonType = entry.getValue();
                        return SomeOtherPersonType.builder()
                                .name(somePersonType.getName())
                                .age(somePersonType.getAge())
                                .build();
                    }
            ));

但是,由于您正在使用构建器,那么为什么不让构建器负责从SomeOtherPersonType创建SomePersonType

public SomeOtherPersonType fromSomePersonType(SomePersonType) {
     ...
}

这样你就可以:

Map<String, SomeOtherPersonType> someOtherPersonTypeMap = somePersonTypeMap.entrySet()
            .stream()
            .collect(Collectors.toMap(
                    Map.Entry::getKey,
                    entry -> SomeOtherPersonType.builder()
                                .fromSomePersonType(entry.getValue())
                                .build()
            ));