Lambda表达式内部的Math.toIntExact?

时间:2018-11-16 08:09:31

标签: java lambda

我正在学习lambda表达式。 给定一个名称列表,我想计算以N开头的名称的数量。

我做到了:

final static List<String> friends = Arrays.asList("Brian", "Nate", "Neal", "Raju", "Sara", "Scott");

public static int countFriendsStartWithN() {
    return  Math.toIntExact(friends
            .stream()
            .filter(name -> name.startsWith("N"))
            .count());
}

对count方法的调用返回一个原语long,但我想要一个int
我使用Math.toIntExact来获取long的值int

是否可以直接在lambda表达式内获取int值?

5 个答案:

答案 0 :(得分:6)

否,不可能将对toIntExact的调用放入方法调用链,即流管道中。这是因为count终端操作,并且返回原语long,在该原语上不可能进行任何方法调用。终端操作是结束流管道并产生结果(或副作用)的操作。

因此,我相信您可以做的最好的事情就是继续使用已有的代码。恕我直言,很好。

答案 1 :(得分:5)

好吧,这是一种在不进行强制转换的情况下将计数计算为int的方法,有点愚蠢:

public static int countFriendsStartWithN() {
    return friends.stream()
                  .filter(name -> name.startsWith("N"))
                  .mapToInt (s -> 1)
                  .sum();
}

答案 2 :(得分:4)

您无法在当前具有的lambda表达式内执行任何操作,因为这是一个谓词:它返回一个布尔值。 Math.toIntExact返回int

您可以在没有Math.toIntExact(或简单的演员表)的情况下完成此操作,

return /* create stream, filter */
    .mapToInt(a -> 1).sum();

但是这可能比现在做的要慢。

答案 3 :(得分:3)

还有另一种效果并不理想的选择-可以使用套用整理器的收集器:

public static int countFriendsStartWithN() {
    return friends.stream()
                .filter(name -> name.startsWith("N"))
                .collect(Collectors.collectingAndThen(Collectors.counting(), Math::toIntExact));
}

如果您经常需要它可能会有一个好处-您可以构建一个实用工具方法,返回此Collector以使其可重复使用。

答案 4 :(得分:2)

这是使用reduce

的一种方法
public static int countFriendsStartWithN2() {
    return friends
            .stream()
            .filter(name -> name.startsWith("N"))
            .map(s -> 1)
            .reduce(0, Integer::sum);
}