区分Java中的不同数据类型

区分Java中的不同数据类型,java,arraylist,Java,Arraylist,我有一个包含以下内容的文本文件: Hello 1 2 3 4 5.6 LOL 23.5 34.6 23 456 Rofl. 我用java写下了可以读取文本文件内容并区分3种数据类型的代码。唯一的问题是,它将任何整数也转换为双倍数。例如,下面是我的代码输出的内容: List of integers in the textfile: [1, 2, 3, 4, 23, 456] List of doubles in the textfile: [1.0, 2.0, 3.0, 4.0, 5.6, 2

我有一个包含以下内容的文本文件:

Hello
1
2
3
4
5.6
LOL
23.5
34.6
23
456
Rofl.
我用java写下了可以读取文本文件内容并区分3种数据类型的代码。唯一的问题是,它将任何整数也转换为双倍数。例如,下面是我的代码输出的内容:

List of integers in the textfile: [1, 2, 3, 4, 23, 456]

List of doubles in the textfile: [1.0, 2.0, 3.0, 4.0, 5.6, 23.5, 34.6, 23.0, 456.0]

List of Strings in the textfile: [Hello, 5.6, LOL, 23.5, 34.6, Rofl]
我想防止这种情况发生。如有任何建议,将不胜感激

    ArrayList<Integer> data_int=new ArrayList<Integer>();
    ArrayList<String> data_String=new ArrayList<String>();
    ArrayList<Double> data_double=new ArrayList<Double>();


    while(file.hasNext())
    {
        String s=file.next();
        System.out.println(s);

        try
        {
            Integer.parseInt(s);
            data_int.add(Integer.parseInt(s));
         }
        catch(NumberFormatException e)
        {
          data_String.add(s);
        }

        try
        {
              Double.parseDouble(s);
              data_double.add(Double.parseDouble(s)); 

        }
        catch(NumberFormatException e)
        {

        }

    }
    System.out.println("List of integers in the textfile: "+data_int);
    System.out.println("List of doubles in the textfile: "+data_double);
    System.out.println("List of Strings in the textfile: "+data_String);
ArrayList data_int=new ArrayList();
ArrayList data_String=新的ArrayList();
ArrayList data_double=新的ArrayList();
while(file.hasNext())
{
字符串s=file.next();
系统输出打印项次;
尝试
{
整数.parseInt(s);
data_int.add(Integer.parseInt);
}
捕获(数字格式)
{
数据字符串。添加;
}
尝试
{
Double.parseDouble(s);
data_double.add(double.parseDouble(s));
}
捕获(数字格式)
{
}
}
System.out.println(“文本文件中的整数列表:“+data\u int”);
System.out.println(“文本文件中的双精度列表:“+data\u double”);
System.out.println(“文本文件中的字符串列表:“+data\u String”);

对收到的每个令牌尝试以下操作:

  • 尝试将令牌解析为
    int
    -如果通过,请不要尝试将其解析为
    int
    字符串
  • 如果失败,请尝试将令牌解析为
    双精度
    。如果通过,请不要尝试将其解析为
    字符串
  • 如果失败,则将令牌解析为
    字符串

  • 删除之前每次解析尝试失败时将数据添加到字符串数据集的代码。

    我认为下面应该适合您

    while(file.hasNext()){
            String s=file.next();
            System.out.println(s);  
    
            try
            {
                  try
                   {
                    Integer.parseInt(s);
                    data_int.add(Integer.parseInt(s));
                   }
                   catch(NumberFormatException e){
                    //do nothing
                   }
                  Double.parseDouble(s);
                  data_double.add(Double.parseDouble(s)); 
            }
            catch(NumberFormatException e){
            data_String.add(s);
            }
        }
    

    与其调用
    parseInt
    parseDouble
    然后处理异常,不如使用带有
    String#matches
    的正则表达式来查看值是整数还是双精度。例外情况是指正常流量以外发生的特殊情况;您不希望使用它们来控制程序的常规流。由于可以预期会有非数值,因此最好检查该值并查看其“外观”

    要查看它是否是整数,您可以使用
    -?\\d+

    对于double,请使用正则表达式
    -?\\d*\.\\d+
    。这甚至会匹配
    .5
    格式的字符串


    如果这些都不匹配,它可能是一个字符串。

    在catch块中进行双重检查以进行整数检查

    try {
      Integer.parseInt(s);
      data_int.add(Integer.parseInt(s));
    } catch(NumberFormatException e) {
      try {
        Double.parseDouble(s);
        data_double.add(Double.parseDouble(s));
      } catch(NumberFormatException e) {
        data_String.add(s);
      }
    }
    

    使用嵌套的Try-Catch块:

    while (file.hasNext()) {
    
        String s = file.next();
        System.out.println(s);
    
        try {
            Integer.parseInt(s);
            data_int.add(Integer.parseInt(s));
        } catch (Exception e) {
    
            try {
                Double.parseDouble(s);
                data_double.add(Double.parseDouble(s));
            } catch (Exception e1) {
                // TODO Auto-generated catch block
                data_String.add(s);
            }
        }
    
    }
    

    你可能是说他需要先尝试将其解析为int,因为double将同时解析整数值和double,而parseint将只解析整数值而不是double。1+以上的注释这个链接有一个非常可靠的答案:你的整数正则表达式不会匹配负数,你的双正则表达式将不匹配指数符号。因为你的正则表达式充其量只能简单地预测
    parseInt
    parseDouble
    已经做了什么,所以试图定义正确的正则表达式似乎没有什么帮助-让现有的解析器为你做就行了。@dimo414将正则表达式更改为匹配负数很简单。因为OP没有指定他处理的是指数符号,所以我认为没有必要在正则表达式中包含指数符号,但是如果也包含指数符号,那就很简单了。将异常用于控制流完全避开了异常的实际用途。此外,您的性能将非常糟糕,因为每次遇到非数字值时都会引发两个异常。当然,您可以整理正则表达式,但当您最终正确匹配所有可解析整数和双精度时,您只是复制了
    parseInt
    parseDouble
    的行为,然后在实际运行它们时,它们必须不必要地重新验证字符串。如果不进行基准测试,我们任何一方猜测哪种情况更糟都是白费口舌,但至少双方都不是明确的赢家。另一方面,预验证增加的代码复杂度相对较高。我尊重你的意思,但至少就我个人而言,我不会这么做。有多少“所有可解析整数”<代码>-?\d+
    将匹配任何整数,并将匹配浮点数(包括指数)。问题是Java不提供“try parse”功能,如果您想避开性能问题,就必须进行复制。快速基准;解析速度几乎是使用正则表达式速度的五倍(在我的盒子上;YMMV)。预验证甚至没有那么复杂。另一个例子:2^32传递您的正则表达式,但不是有效的整数。我很清楚这段代码背后的解释,第一次尝试解析整数。如果这不起作用,在catch语句中还有另一次尝试将其解析为双精度。如果不起作用,它被认为是一个字符串,对吗?