转换为函数 Java 样式
Converting to functional Java style
如何使用过滤器、收集器等以适当的 Java 8 种功能样式重写以下内容:
private 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);
BigInteger result = BigInteger.ONE;
for (char c : letters) {
//System.out.println(c+"="+(int)c);
if (c < OFFSET) {
return new BigInteger("-1");
}
int pos = c - OFFSET;
result = result.multiply(bigPrimes[pos]);
}
return result;
}
@Test public void test() {
assertThat(calculateProduct(capitalize("carthorse"))).isEqualTo(calculateProduct(capitalize("orchestra")));
}
private char[] capitalize(String word) {
return word.toUpperCase().toCharArray();
}
我不知道你为什么想要那个,但可能是这个(它创建了更多的对象并且更冗长):
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);
}
}
你可以这样做:
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);
}
如何使用过滤器、收集器等以适当的 Java 8 种功能样式重写以下内容:
private 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);
BigInteger result = BigInteger.ONE;
for (char c : letters) {
//System.out.println(c+"="+(int)c);
if (c < OFFSET) {
return new BigInteger("-1");
}
int pos = c - OFFSET;
result = result.multiply(bigPrimes[pos]);
}
return result;
}
@Test public void test() {
assertThat(calculateProduct(capitalize("carthorse"))).isEqualTo(calculateProduct(capitalize("orchestra")));
}
private char[] capitalize(String word) {
return word.toUpperCase().toCharArray();
}
我不知道你为什么想要那个,但可能是这个(它创建了更多的对象并且更冗长):
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);
}
}
你可以这样做:
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);
}