从String获取double值获取java.util.NoSuchElementException

时间:2014-08-26 09:07:53

标签: java

我使用以下逻辑从String中提取double值。它在第一个String上工作正常但在第二个String上引发异常。引发的异常为java.util.NoSuchElementException

public class StringHandling {

   public String processString(String string)
   {
        Scanner st = new Scanner(string);
        while (!st.hasNextDouble())
        {
            st.next();
        }
        double value = st.nextDouble();
        return String.valueOf(value);
   }

   public static void main(String[] args) 
   {
        String first = "Hey, he is 70.3 miles away.";
        String second = "{\"Hey\", \"he\" \"is\": 1.0, \"miles\" away}";
        StringHandling sh = new StringHandling();
        System.out.println("First Value is "+sh.processString(first));
        System.out.println("Second Value is "+sh.processString(second));
   }
}

我只是想知道为什么它会引发异常。

3 个答案:

答案 0 :(得分:3)

这是问题所在:

"{\"Hey\", \"he\" \"is\": 1.0, \"miles\" away}"

默认情况下,类next的{​​{1}}方法会为您提供下一个输入,直到达到空格。

Scanner方法可以像这样获取它:

next

在这种情况下,您有{"Hey", "he" "is": 1.0, "miles" away} a 1.0,(请注意逗号)。

这就是为什么你得到double的原因:你继续NoSuchElementException,但是找不到st.next(),所以字符串的结尾到了,而且扫描器没有找不到其他元素。

答案 1 :(得分:0)

您可以使用正则表达式而不是扫描程序:

public String processString(String string) {
   Pattern p = Pattern.compile("(\\d+(?:\\.\\d+))");
   Matcher m = p.matcher(string);
   while(m.find()) {
       return m.group(1);
   }
   return null;
}

答案 2 :(得分:0)

问题

默认情况下,Scanner分隔在空白处。因此,您的第二个示例将1.0,视为输入之一,它不会将其识别为double。

您的代码还假设您将退出while循环,因为您找到了double。在这种情况下,没有值可读,所以你得到一个例外。

解决方案1 ​​ - 更改分隔符

一种选择是更改Scanner对象使用的分隔符。也许是这样的:

st.useDelimiter("[^\\w.]");

这会将您的输入分为“单词”,其中包含字母数字字符,下划线和句号的任意组合。

解决方案2 - 正则表达式

您可以使用正则表达式找到此值。下面的示例查找包含小数点和至少一个小数位的数字:

public static String findWithRegex(String string) {
    Pattern pattern = Pattern.compile("\\d+\\.\\d+");
    Matcher matcher = pattern.matcher(string);
    if (matcher.find()) {
        return matcher.group();
    } else {
        // do something more useful here
        return "none";
    }
}