转换为功能性Java风格

时间:2017-10-01 21:35:10

标签: functional-programming java-8 refactoring functional-java

如何使用过滤器,收集器等以适当的Java 8功能样式重写以下内容:

$arg_<argname>

2 个答案:

答案 0 :(得分:2)

我不知道为什么你想要那个,但可能是这个(它创造了更多的对象并且更加冗长):

private static BigInteger calculateProduct(char[] letters) {

    int OFFSET = 65;

    BigInteger[] bigPrimes = Arrays.stream(
            new int[] { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31,
                    37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89,
                    97, 101, 103, 107, 109, 113 })
            .mapToObj(BigInteger::valueOf)
            .toArray(BigInteger[]::new);

    Optional<Character> one = IntStream.range(0, letters.length)
            .mapToObj(x -> letters[x])
            .filter(x -> x < OFFSET)
            .findAny();

    if (one.isPresent()) {
        return new BigInteger("-1");
    } else {
        return IntStream.range(0, letters.length)
                .mapToObj(x -> letters[x])
                .parallel()
                .reduce(
                        BigInteger.ONE,
                        (x, y) -> {
                            int pos = y - OFFSET;
                            return x.multiply(bigPrimes[pos]);
                        },
                        BigInteger::multiply);
    }

}

答案 1 :(得分:2)

你可以这样做:

static final BigInteger[] PRIMES
    = IntStream.of(
        2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53,
        59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113)
    .mapToObj(BigInteger::valueOf)
    .toArray(BigInteger[]::new);

private BigInteger calculateProduct(char[] letters) {
    final int OFFSET = 65;
    final CharBuffer cb = CharBuffer.wrap(letters);
    if(cb.chars().anyMatch(c -> c<OFFSET))
        return BigInteger.ONE.negate();
    return cb.chars()
        .mapToObj(c -> PRIMES[c-OFFSET])
        .reduce(BigInteger.ONE, BigInteger::multiply);
}

请注意,将PRIMES数组的创建移出方法,以避免为每次调用再次生成它,是一项改进,无论您是使用循环还是“功能样式”操作都可以。

此外,您的代码不会处理太大的字符,因此您可以将方法改进为

private BigInteger calculateProduct(char[] letters) {
    final int OFFSET = 65;
    final CharBuffer cb = CharBuffer.wrap(letters);
    if(cb.chars().mapToObj(c -> c-OFFSET).anyMatch(c -> c<0||c>PRIMES.length))
        return BigInteger.ONE.negate();
    return cb.chars()
        .mapToObj(c -> PRIMES[c-OFFSET])
        .reduce(BigInteger.ONE, BigInteger::multiply);
}