Java流>;可以内联一个;orElseGet“;进入父流?

Java流>;可以内联一个;orElseGet“;进入父流?,java,java-8,java-stream,optional,Java,Java 8,Java Stream,Optional,我不知道该如何确切地界定这个问题,所以请容忍我 1)除了添加null并随后过滤掉null之外,还有没有更好(也就是更“合适”)的方法来实例化可选元素的流 Stream.of( ... , person.likesRed() ? Color.RED : null) .filter(Objects::nonNull) ... 2)其次,是否有办法将以下或lseget函数“内联”到父流中/映射 .map(p -> ofNullable(p.getFavourit

我不知道该如何确切地界定这个问题,所以请容忍我

1)除了添加
null
并随后过滤掉
null
之外,还有没有更好(也就是更“合适”)的方法来实例化可选元素的

Stream.of( ... ,
        person.likesRed() ? Color.RED : null)
        .filter(Objects::nonNull)
...
2)其次,是否有办法将以下
或lseget
函数“内联”到父
流中
/
映射

.map(p -> ofNullable(p.getFavouriteColours()).orElseGet(fallbackToDefaultFavouriteColours))
完整(人为)示例:

import static java.util.Optional.ofNullable;
公共响应GetFavoriteColor(最终字符串personId){
Person-Person=personService.findById(personId);
供应商回退至默认收藏夹颜色=()->
溪流(
颜色,蓝色,
颜色,绿色,
person.likesRed()?Color.RED:null)
.filter(对象::非空)
.map(颜色::getName)
.collect(Collectors.toList());
归还可赎回资产(人)
.map(p->ofNullable(p.GetFavoriteColor()).OrelGet(FallbacktoDefaultFavoriteColor))
.map(响应::createSuccess)
.orElse(响应::createNotFound);
}

一个更简洁的表达式应该是

Stream.concat(Stream.of(Color.BLUE, Color.GREEN),
              person.likesRed()? Stream.of(Color.RED): Stream.empty())
这并不比原始表达式简单,但它不会产生插入某些内容只是为了在事后过滤掉它的不良感觉,或者更抽象地说,不会产生丢弃必须在事后重建的已知信息的不良感觉

甚至还有技术上的差异。上面的表达式创建了一个具有已知大小的流,可用于优化某些操作。相比之下,使用
过滤器的变量只有一个估计大小,即过滤前的元素数,而不是已知的精确大小

通过不过度使用
可选
,可以大大简化周围的代码:

public Response getFavouriteColours(final String personId) {
    Person person = personService.findById(personId);
    if(person == null) return Response.createNotFound();

    List<String> favouriteColours = person.getFavouriteColours();
    if(favouriteColours == null)
        favouriteColours = Stream.concat(
                Stream.of(Color.BLUE, Color.GREEN),
                person.likesRed()? Stream.of(Color.RED): Stream.empty())
            .map(Color::getName)
            .collect(Collectors.toList());

    return Response.createSuccess(favouriteColours);
}
公共响应GetFavoriteColor(最终字符串personId){
Person-Person=personService.findById(personId);
if(person==null)返回Response.createNotFound();
List FavoriteColors=person.getFavoriteColors();
if(favoriteColors==null)
收藏夹颜色=Stream.concat(
流(颜色。蓝色,颜色。绿色),
person.likesRed()?Stream.of(Color.RED):Stream.empty())
.map(颜色::getName)
.collect(Collectors.toList());
返回响应。createSuccess(FavoriteColor);
}
甚至流操作本身也不比这里的常规命令式代码简单:

public Response getFavouriteColours(final String personId) {
    Person person = personService.findById(personId);
    if(person==null) return Response.createNotFound();

    List<String> favouriteColours = person.getFavouriteColours();
    if(favouriteColours==null) {
        favouriteColours=new ArrayList<>();
        Collections.addAll(favouriteColours, Color.BLUE.getName(), Color.GREEN.getName());
        if(person.likesRed()) favouriteColours.add(Color.RED.getName());
    }
    return Response.createSuccess(favouriteColours);
}
公共响应GetFavoriteColor(最终字符串personId){
Person-Person=personService.findById(personId);
if(person==null)返回Response.createNotFound();
List FavoriteColors=person.getFavoriteColors();
if(favoriteColors==null){
FavoriteColors=新的ArrayList();
Collections.addAll(favoriteColors、Color.BLUE.getName()、Color.GREEN.getName());
if(person.likesRed())favoriteColors.add(Color.RED.getName());
}
返回响应。createSuccess(FavoriteColor);
}

虽然更复杂的示例可能会从流API的使用中受益,但使用Optional不太可能在更复杂的操作中得到更好的效果。如果链中的所有缺失值或过滤器不匹配都应该在链的末尾以相同的方式处理,那么一系列可选操作可以简化代码。但是,如果像您的示例(以及大多数实际场景)中那样,每个缺少的值都应该得到不同的处理或单独报告,那么使用Optional,尤其是嵌套使用Optionals,并不能改善代码。

Nah,这看起来和它得到的一样好。我支持这一点。我看不出您当前的代码有任何改进的余地。事实上,情况就是这样。但是,我认为您可以使用一些默认的/NONE颜色枚举常量来代替
null
,但这是一个意见问题。您的意思是
.orElseGet(Response::createNotFound)
public Response getFavouriteColours(final String personId) {
    Person person = personService.findById(personId);
    if(person==null) return Response.createNotFound();

    List<String> favouriteColours = person.getFavouriteColours();
    if(favouriteColours==null) {
        favouriteColours=new ArrayList<>();
        Collections.addAll(favouriteColours, Color.BLUE.getName(), Color.GREEN.getName());
        if(person.likesRed()) favouriteColours.add(Color.RED.getName());
    }
    return Response.createSuccess(favouriteColours);
}