使用 Lambdas 将字符串转换为整数值
Convert String to Integer value using Lambdas
如何使用 Java 8 个 lambda 将 String
转换为 int
值?
我试过像这样将 String
转换成 IntStream
,并在其上应用方法 mapToInt
但出现错误,
int x = "582564625".chars().boxed().mapToInt(???)
我真正想要的是,将“582564625”转换为 int
值并将其存储在变量 x
.
中
在上一行中,我应该用什么替换???
?
Java 8 个流旨在用于值流,而不是单个值。在您的情况下,原始 String
和 int
是单个值,因此这不是一个好的流用例。
如果您想将字符串转换为其数字集,例如,对可能使用流的数字求和。
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);
但这可能和看起来一样毫无意义!
虽然 provides a solution which works in a sequential context, the provided function violates the associativity contract which the specification of reduce
mandates. This will fail as soon as you start using parallel
流。
如果您考虑尝试处理输入值 1000
时会发生什么,则无法使用 int
值提供正确的关联函数。您不能单独处理 10
和 00
然后合并它们的结果。
要解决这个问题,您需要一个包含实际数值和相关位数的值。如果值类型是不可变的或至少被视为不可变的,则可以将 reduce
与此类值类型一起使用。这意味着可能为每个操作创建实例,因此我更喜欢使用 Mutable Reduction 的替代方法,我们使用可变容器保存当前值和位数。如果我们不想为此引入新的 class
,我们可以简单地使用长度为 2 的 int[]
数组:
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
,每个线程在调用第二个函数之前将使用该容器,第二个函数使用知识 [=22] 向容器添加值=] 模式并通过将因子(最初为 1
)乘以 10
.
来增加位数
第三个函数将连接两个容器,并在两个线程完成工作后调用。它将使用代表位数的因子用第二个容器的值更新第一个容器。
毕竟,这确实是一个有趣的问题来证明流处理的原理,即使 Integer.parseInt
对于所有 String
长度来说更简单并且总是更快,而值仍然适合 int
。应该注意的是,这个例子不检查任何错误条件,而只是为非法字符产生废话。
如何使用 Java 8 个 lambda 将 String
转换为 int
值?
我试过像这样将 String
转换成 IntStream
,并在其上应用方法 mapToInt
但出现错误,
int x = "582564625".chars().boxed().mapToInt(???)
我真正想要的是,将“582564625”转换为 int
值并将其存储在变量 x
.
在上一行中,我应该用什么替换???
?
Java 8 个流旨在用于值流,而不是单个值。在您的情况下,原始 String
和 int
是单个值,因此这不是一个好的流用例。
如果您想将字符串转换为其数字集,例如,对可能使用流的数字求和。
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);
但这可能和看起来一样毫无意义!
虽然 reduce
mandates. This will fail as soon as you start using parallel
流。
如果您考虑尝试处理输入值 1000
时会发生什么,则无法使用 int
值提供正确的关联函数。您不能单独处理 10
和 00
然后合并它们的结果。
要解决这个问题,您需要一个包含实际数值和相关位数的值。如果值类型是不可变的或至少被视为不可变的,则可以将 reduce
与此类值类型一起使用。这意味着可能为每个操作创建实例,因此我更喜欢使用 Mutable Reduction 的替代方法,我们使用可变容器保存当前值和位数。如果我们不想为此引入新的 class
,我们可以简单地使用长度为 2 的 int[]
数组:
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
,每个线程在调用第二个函数之前将使用该容器,第二个函数使用知识 [=22] 向容器添加值=] 模式并通过将因子(最初为 1
)乘以 10
.
第三个函数将连接两个容器,并在两个线程完成工作后调用。它将使用代表位数的因子用第二个容器的值更新第一个容器。
毕竟,这确实是一个有趣的问题来证明流处理的原理,即使 Integer.parseInt
对于所有 String
长度来说更简单并且总是更快,而值仍然适合 int
。应该注意的是,这个例子不检查任何错误条件,而只是为非法字符产生废话。