Java 8流映射,将空值保持为null

时间:2016-07-23 21:35:13

标签: java lambda java-stream

我有这段代码:

public LatLng[] locationDtoListToLatLngArray(List<LocationDto> locationDtoList) {
    return locationDtoList.stream()
            .map(locationDto -> new LatLng(locationDto.getLatitude(), locationDto.getLongitude()))
            .toArray(LatLng[]::new);
}

但如果locationDto

中的null.map,则会崩溃

我修好了这样做:

public LatLng[] locationDtoListToLatLngArray(List<LocationDto> locationDtoList) {
    return locationDtoList.stream()
            .map(locationDto -> locationDto == null ? null : new LatLng(locationDto.getLatitude(), locationDto.getLongitude()))
            .toArray(LatLng[]::new);
}

但我想知道是否有更好的方法(不检查是否locationDto == null

请注意,如果locationDto == null,我想保留null,那么过滤器不是一个选项:)

由于

编辑:我知道问题是访问一个空对象,我只想知道是否有像.map()那样的功能,我需要做什么,.mapKeepingNulls(),就像这样。

编辑2:我最终这样做了:

public LatLng[] locationDtoListToLatLngArray(List<LocationDto> locationDtoList) {
    return locationDtoList.stream()
            .map(this::locationDtoToLatLng)
            .toArray(LatLng[]::new);
}

private LatLng locationDtoToLatLng(LocationDto locationDto) {
    if (locationDto == null) {
        return null;
    }
    return new LatLng(locationDto.getLatitude(), locationDto.getLongitude());
}

3 个答案:

答案 0 :(得分:2)

问题是您正在访问具有潜在null值的方法。如果您真的不想在那里进行空检查(我认为这是一个很好的解决方案),您可以尝试在LatLng中创建一个静态方法,该方法将采用LocationDto并返回正确的实例或当提供的nullLocationDto时,null

这样的事情:

public static LatLng getFromLocationDto(LocationDto ldt){
    if(ldt == null)
        return null;

    return new LatLng(ldt.getLatitude(), ldt.getLongitude());
}

但是null检查必须在某处(除非您可以确保null中没有locationDtoList

答案 1 :(得分:0)

这个问题与Java 8流没什么关系。在执行NullPointerException时,您获得了locationDto.getLatitude()

检查空值是完全正常的。如果你不在一个小溪里,我几乎可以肯定你不会打扰你。

也许您不喜欢的事实是您在单行中执行内联条件操作,在这种情况下,我建议您使用辅助函数(如_createLatLng(LocationDto locationDto))来外化该过程。

答案 2 :(得分:0)

您可以使用Optional,它是为此目的而在Java 8中创建的新类。

//将locationDtoList转换为Optional

列表
locationDtoList.stream()
        .filter(Optional::isPresent)
        .map(Optional::get)
        .map(locationDto -> new LatLng(locationDto.getLatitude(),      locationDto.getLongitude()))
        .toArray(LatLng[]::new);