映射方法引用链

2022-09-01 11:02:05

我正在与Twitter4J合作。但我问的问题更笼统。我想访问给定推文的用户 ID。目前,我有以下两个选择:

//Option 1
stream.map(status -> status.getUser().getId())
      .forEach(System.out::println);

//Option 2:
stream.map(Status::getUser)
      .map(User:getId)
      .forEach(System.out::println);

我不喜欢第一个选项中的lambda表达式,也不喜欢第二个选项中的被迫调用两个。有没有办法制作一个方法引用链?我知道这行不通,但我想知道是否有其他选择。mapsStatus::getUser::getId


答案 1

不,这是两种方法。其他任何事情最终都只会变得不那么清楚。

但是,既然您询问了,这里有一些选择。

static<T,U,R> Function<T,R> chain(
        Function<? super T, ? extends U> f1,
        Function<? super U, ? extends R> f2) {
    return t -> f2.apply(f1.apply(t));
}

stream.map(chain(Status::getUser, User::getId))

static<T,R> Function<T,R> func(Function<T,R> f) {
    return f;
}

stream.map(func(Status::getUser).andThen(User::getId))

答案 2

在提出的两个选项中,我倾向于使用第二个选项,将调用链接到 。map()

还有其他选项,它们使用内置 API 而不是帮助器方法,如下所示使用 Function.compose()Function.andThen() 方法,您可以链接函数调用。 和其他功能接口实现类似的默认方法。Predicate

stream.map(((Function<Status, User>) Status::getUser).andThen(User::getId))
  .forEach(System.out::println);

或者

Function<Status, User> toUser = Status::getUser;
stream.map(toUser.andThen(User::getId)).forEach(System.out::println);

缺点是,为了使用这些,必须显式给出功能接口类型。这需要一个演员或一个任务,这看起来有点丑陋。因此,对于映射链,我通常使用多个调用。map()


推荐