我对@Misha 的回答做出了贡献,因为我找到了一个示例,我们希望使用 BigInteger 而不是原始数据类型进行乘法运算。
我正在解决这个 kata:Numbers with this digit inside,其中我们得到 x:一个 int 和 d:一个数字。我们需要找到从 1 到 x 中包含 d 的数字,并将其计数、和和乘法作为长数组返回。
首先我尝试了以下代码:
import java.util.*;
public class Kata
{
public static long[] NumbersWithDigitInside(long x, long d)
{
if(d > x) return new long[3];
List<Integer> list = new ArrayList<Integer>();
for(int i = 1; i <= x; i++){
String current = String.valueOf(i);
if(current.contains(String.valueOf(d))){
list.add(i);
}
}
return new long[]{list.size(),
list.stream().mapToInt(Integer::intValue).sum(),
list.stream().reduce(1, (a,b) -> a*b)};
}
}
当我们执行以下测试时:
import org.junit.Test;
import static org.junit.Assert.assertArrayEquals;
import org.junit.runners.JUnit4;
public class SolutionTest {
@Test
public void BasicTests() {
assertArrayEquals(new long[] { 0, 0, 0 }, Kata.NumbersWithDigitInside(5, 6));
assertArrayEquals(new long[] { 1, 6, 6 }, Kata.NumbersWithDigitInside(7, 6));
assertArrayEquals(new long[] { 3, 22, 110 }, Kata.NumbersWithDigitInside(11, 1));
assertArrayEquals(new long[] { 2, 30, 200 }, Kata.NumbersWithDigitInside(20, 0));
assertArrayEquals(new long[] { 9, 286, 5955146588160L }, Kata.NumbersWithDigitInside(44, 4));
}
}
它输出:
arrays first differed at element [2]; expected:<5955146588160> but was:<-1973051392>
因为在尝试最后一个测试用例时失败:
assertArrayEquals(new long[] { 9, 286, 5955146588160L }, Kata.NumbersWithDigitInside(44, 4));
所以要检查它是否是由于我替换的溢出:
list.stream().reduce(1, (a,b) -> a*b)};
与:
list.stream().mapToInt(num->num).reduce(1, Math::multiplyExact)};
那么,它会输出:
java.lang.ArithmeticException: integer overflow
最后我使用 BigInteger 如下:
list.stream().map(BigInteger::valueOf).reduce(BigInteger.ONE, BigInteger::multiply).longValue()}
作为完整的代码:
import java.util.*;
import java.math.BigInteger;
public class Kata
{
public static long[] NumbersWithDigitInside(long x, long d)
{
List<Integer> list = new ArrayList<Integer>();
for(int i = 1; i <= x; i++){
String current = String.valueOf(i);
if(current.contains(String.valueOf(d))){
list.add(i);
}
}
if(list.size() == 0) return new long[3];
return new long[]{list.size(),
list.stream().mapToInt(Integer::intValue).sum(),
list.stream().map(BigInteger::valueOf).reduce(BigInteger.ONE, BigInteger::multiply).longValue()};
}
}
➡️欲了解更多信息:
BigInteger class
longValue()