Math.toIntExact внутри лямбда-выражения? - PullRequest
0 голосов
/ 16 ноября 2018

Я изучаю лямбда-выражения.Учитывая список имен, я хочу посчитать количество имен, которые начинаются с 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.

Можно ли получить значение int непосредственно внутри лямбды?выражение?

Ответы [ 5 ]

0 голосов
/ 16 ноября 2018

Еще один вариант, который на самом деле не лучше - можно использовать коллектор, который применяет финишер:

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

Это может иметь преимущество, если вам это нужно часто - вы можете создать служебный методвозвращая это Collector, чтобы сделать его многоразовым.

0 голосов
/ 16 ноября 2018

Вот способ сделать это с reduce

public static int countFriendsStartWithN2() {
    return friends
            .stream()
            .filter(name -> name.startsWith("N"))
            .map(s -> 1)
            .reduce(0, Integer::sum);
}
0 голосов
/ 16 ноября 2018

Вы не можете ничего сделать внутри лямбда-выражения, которое у вас есть в данный момент, так как это предикат: он возвращает логическое значение. Math.toIntExact возвращает int.

Вы можете сделать это без Math.toIntExact (или простого приведения), например:

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

Но это, вероятно, будет медленнее, чем то, что вы делаете в данный момент.

0 голосов
/ 16 ноября 2018

Хорошо, вот несколько глупый способ подсчета числа как целого без приведения:

public static int countFriendsStartWithN() {
    return friends.stream()
                  .filter(name -> name.startsWith("N"))
                  .mapToInt (s -> 1)
                  .sum();
}
0 голосов
/ 16 ноября 2018

Нет, невозможно вписать ваш вызов toIntExact в вашу цепочку вызовов методов, в ваш потоковый конвейер .Это потому, что count является терминальной операцией и возвращает примитив long, для которого вызов метода невозможен.Терминальная операция - это операция, которая завершает конвейер потока и дает результат (или побочный эффект).

Поэтому я считаю, что лучшее, что вы можете сделать, - это жить с кодом, который у вас уже есть.ИМХО все нормально.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...