使用Lambdas将String转换为Integer值

时间:2015-02-03 20:23:28

标签: java lambda java-8

如何使用Java 8 lambdas将String转换为int值?

我试图像这样将String转换为IntStream,并在其上应用方法mapToInt,但它会出错,

    int x = "582564625".chars().boxed().mapToInt(???)

我真正想要的是,将“582564625”转换为int值并将其存储在变量x中。

在上面一行中,我应该用{<1}}替换什么?

2 个答案:

答案 0 :(得分:3)

Java 8流旨在用于值流,而不是单个值。在您的情况下,原始Stringint是单个值,因此这不是流的良好用例。

如果您希望将String转换为其数字集,例如,将可能使用流的数字相加。

numberString.chars().map(n -> Character.digit(n, 10)).sum();

但只是明确地回答你的问题,如果你特别想转换为数字然后转换回你可以做的int:

int n = numberString.chars()
    .map(n -> Character.digit(n, 10))
    .reduce(0, (n, d) -> n * 10 + d);

但这看起来可能毫无意义!

答案 1 :(得分:2)

虽然sprinter’s answer提供了在顺序上下文中工作的解决方案,但提供的功能违反了associativity contract强制要求的specification of reduce。一旦开始使用parallel流,这将失败。

如果您考虑在尝试处理输入值int时会发生什么,则无法使用1000值提供正确的关联函数。您无法单独处理1000并随后加入其结果。

要解决此问题,您需要一个既包含实际数值又包含相关位数的值。如果值类型是不可变的或至少被视为不可变,则可以将reduce与此类值类型一起使用。这可能意味着每个操作都有可能的实例创建,因此我更喜欢使用Mutable Reduction,我们使用一个容纳当前值和位数的可变容器。如果我们不想为此引入新的int[],我们可以简单地使用长度为2的class数组:

int iValue = numberString.chars()
    .map(n -> Character.digit(n, 10))
    .parallel()
    .collect(()->new int[]{0,1},
             (ia, v) -> { ia[0]=ia[0]*10 + v; ia[1]*=10; },
             (ia1, ia2) -> { ia1[0]=ia1[0]*ia2[1]+ia2[0]; ia1[1]*=ia2[1]; })[0];

实际值在第一个元素中携带,并且在第二个元素中携带数字的位数是在并发计算后必须合并两个容器时所需的因子形式。

所以第一个函数()->new int[]{0,1}实现了一个新容器的Supplier,在调用第二个函数之前,每个线程将使用它来使用知道x=x*10+y向容器添加一个值模式并通过将因子(最小为1)乘以10来提高位数。

第三个函数将连接两个容器,一旦两个线程完成其工作将被调用。它将使用表示数字位数的因子更新第一个容器,使用第二个容器的值。


毕竟,这确实是一个有趣的问题,用于演示流处理的原则,即使Integer.parseInt更简单,并且对于String长度的所有int长度总是更快,{{1}} }。应该注意的是,这个例子没有检查任何错误情况,只是对非法字符产生无意义。

相关问题