有没有办法使用 'Optional' 的方法 'orElseGet' 在它为 null 时创建一个新列表?

Is there a way to use method 'orElseGet' of 'Optional' to create a new list when it is null?

假设我们有一个 class 结构如下:

class Resource{
   String id; 
   String name;
   List<String> friends;
}

有没有办法通过这种方式使用'Optional'获取列表:

Optional.of(resource.getFriends()).map(friends -> {
    friends.add("John");
    return friends;
}).orElseGet(
    //do something here.
)

如果之前没有,则需要一个新列表。

这取决于您更精确的功能需求。我提出了几个选项。

如果您只想要一个包含资源好友和 John 的列表:

    List<String> listWithJohn = Optional.ofNullable(resource.getFriends())
            .orElseGet(ArrayList::new);
    listWithJohn.add("John");

正如 Basil Bourque 在评论中提到的那样,由于 Java 9 列表初始化可以改为使用 Objects.requireNonNullElseGet:

    List<String> listWithJohn
            = Objects.requireNonNullElseGet(resource.getFriends(), ArrayList::new);

如果你想把 John 添加到资源的好友中,我建议 getFriends 方法是编辑的地方:

/** @return The list of friends, not null */
public List<String> getFriends() {
    if (friends == null) {
        friends = new ArrayList<>();
    }
    return friends;
}

不过,返回列表本身会使资源容易受到调用者在以后任何时候意外地和不可预测地修改他们的朋友列表的攻击。人们通常希望 return 列表的副本或它的不可修改的视图(防止调用者将 John 添加为朋友)。在这种情况下,资源可以有一个 addFriend 添加朋友的方法。

编辑:

is there a way to make in only one lambda code line?

    friends = friends == null ? new ArrayList<>() : friends;
    return friends;

但我会发现它的可读性较差(那里没有 lambda,它只是一个 one-liner)。或者如果你想让它完全神秘:

    return friends = friends == null ? new ArrayList<>() : friends;

不推荐。