Java中的字符串到整数解决方案

时间:2018-07-13 13:40:42

标签: java string

我发现Java解决了Stringint转换的这种解决方案(来源:“ Java编程访谈的元素” )。谁能告诉我发生了什么事?

public static int stringToInt(String s){
  return (s.charAt(0) == '-' ? -1 : 1) * s.substring(s.charAt(0) == '-' ? 1 :0)
          .chars()
          .reduce(0, (runningSum,c) -> runningSum * 10 + c -'0');
}

我了解第一部分,他们检查String是否以'-'开头,如果是,则将结果乘以-1并仅取不包含' -”。然后怎样呢?他们为什么使用.chars()?在第三行和最后一行,我什至不了解语法。 分步输出将不胜感激。

4 个答案:

答案 0 :(得分:3)

这是流式语法。 string.chars()。reduce(...)大致等同于

int runningSum = 0;
for (int i = string.length() - 1; i >= 0; i ++){
    runningSum *= 10;
    runningSum += string.charAt(i) - '0';
}

您可以在此处了解更多信息:http://winterbe.com/posts/2014/07/31/java8-stream-tutorial-examples/

答案 1 :(得分:3)

为什么要使用.chars()?

因为如果要手动将String转换为int,则需要访问每个char。每个字符包含数字的一位,因此您需要访问每个字符。 String.chars()返回字符串中的字符流。

在第三行也是最后一行,我什至都不懂语法。

让我们分解一下,然后:

Stream.reduce() 将流中的值缩减为一个单一值,使用0作为 identity 值并使用 lambda表达式 (runningSum,c) -> runningSum * 10 + c -'0'作为累加器

Java编译器将lambda表达式(runningSum,c) -> runningSum * 10 + c -'0'转换为BinaryOperator实例。此特定实例接受两个int参数,并将返回一个int结果。您可以想象它看起来像这样:

class CompilerGeneratedBinaryOperator implements BinaryOperator<int> {
    public int apply(int runningSum, int c) {
        return runningSum * 10 + c -'0';
    }
}

reduce 方法随后将循环处理String中的所有字符,始终使用最后一个结果作为下一个runningSum参数(以及 identity 0)。

现在让我们看一下lambda中的语句:runningSum * 10 + c -'0'

这里发生的是,它利用了每个字符的ASCII码。基本上假定它具有一个表示有效整数的字符串,即所有字符都在'0''9'之内。如果您查找ASCII表,您会注意到数字字符的整数表示形式是4857。因此'0'等于48,这意味着当字符c'0'时,其值为48,而c - '0'将为{{ 1}},即48 - 48。如果0c,则'1'将是'1' - '0',依此类推。基本上1给出与该字符表示的数字相对应的整数值。

其余的很简单。它将每个最后的结果乘以c - '0'并加上当前数字,如Michael's answer中所述,当前数字是这样的:

10

答案 2 :(得分:2)

他们要做的是从初始总和0开始,然后对于每个字符中最左边的一个开始,将当前总和乘以10,然后加上当前字符的数值:

例如,“ 123”:

Step 1. 0
Step 2. (0 * 10) + 1 == 1
Step 3. (1 * 10) + 2 == 12
Step 4. (12 * 10) + 3 == 123

在给定累加器的情况下,reduce方法在流上操作以产生某个类型为T(在这种情况下为int)的单个值。
在此累加器case作为lambda表达式(runningSum,c) -> runningSum * 10 + c -'0'(遵循(arguments) -> expression的形式)提供。

chars方法仅用于从'-'之后的字符串部分中获取流,您需要使用它才能使用reduce

'0'用于将字符转换为相应的数值。如果从'0'中减去'0',则得到0;否则,得到0。如果您从'0'中减去'1',则得到1,依此类推。

答案 3 :(得分:2)

对于右边的第一部分,如果存在'-',则将其乘以-1,然后取字符串的另一部分(例如,对于“ -25”,您具有“ 25”)。

然后将其转换为带有“ .chars”的char数组(实际上是IntStream,但大致等于char数组)。

然后,您用reduce取每个数字,该数字取数组中的每个字符并应用lambda(奇怪的“->”表示法)。

您从每个字符中删除“ 0”以得到int值(ASCII码“ 0”为48),将实际总和乘以10,然后将当前字符的值相加。 以-420为例,您有:

  • 1)负号(=>乘-1)
  • 2)char数组[52、50、48](因为在ASCII表中char'4'是52,所以'2'是50 ...)
  • 3)减少:
    • 3.1)52-48 = 4
    • 3.2)4 * 10 +(50-48)= 40 + 2 = 42
    • 3.3)40 * 10 + 2 * 10 +(48-48)= 400 + 20 + 0 = 420
    • 3.4)将解决方案乘以-1 = -420 (来自步骤1)

注意:对不起,我的英语不好,如果您听不懂我说的话,