Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在JAVA中动态确定用户输入数据类型_Java_Json - Fatal编程技术网

在JAVA中动态确定用户输入数据类型

在JAVA中动态确定用户输入数据类型,java,json,Java,Json,我编写了以下代码来确定用户输入的数据类型 更新:删除对浮点的解析,因为双精度值也可以解析为浮点,代价是@DodgyCodeException提到的精度 import java.util.Scanner; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; public class Main { public static void main(String[] arg

我编写了以下代码来确定用户输入的数据类型

更新:删除对
浮点的解析
,因为
双精度
值也可以解析为
浮点
,代价是@DodgyCodeException提到的精度

import java.util.Scanner;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class Main {

    public static void main(String[] args) {
        Scanner src = new Scanner(System.in);
        String input;
        System.out.println("Enter input:");
        input = src.nextLine();
        System.out.println("You entered:" + getDataType(input));
    }

    private static String getDataType(Object input) {
        try {
            JSONObject obj = new JSONObject((String) input);
            return "JSONObject";
        } catch (JSONException ex) {
            try {
                JSONArray array = new JSONArray(input);
                return "JSONArray";
            } catch (JSONException ex0) {
                try {    
                    Integer inti = Integer.parseInt((String) input);
                    return "Integer";
                } catch (NumberFormatException ex1) {
                    try {                          
                            Double dub = Double.parseDouble((String) input);
                            return "Double";
                        } catch (NumberFormatException ex3) {
                            return "String";
                        }
                    }
                }
            }
        }
    }
}
我必须反复运行此操作数百次,我已经了解到捕获
异常
是一项昂贵的操作。
有没有更好的方法来实现这一点

我想知道输入是否是json/jsonarray

您需要处理
JSONException
来确定JSON类型,然后您可以使用方法来确定其他类型,如下所示:

    private static String getDataType(String input) {
       try {
            return getJsonObjectType(input);
        } catch (JSONException ex1) {
            try {
                return getJsonArrayType(input);
            } catch (JSONException ex2) {
                   return getNonJsonType(input);
           }
       }
    }

    private static String getJsonArrayType(String input) throws JSONException {
        new JSONArray(input);
        return "JSONArray";
    }

    private static String getJsonObjectType(String input) throws JSONException {
        new JSONObject((String) input);
        return "JSONObject";
    }

    private static String getNonJsonType(String input) {
        try {
             return getNumberType(input);
         } catch(ParseException ex3) {
             return "String";
         }
    }

    private static String getNumberType(String input) throws ParseException {
         Number number = NumberFormat.getInstance().parse(input);
         if(number instanceof Long) {
             if(number.longValue() < Integer.MAX_VALUE) {
                 return "int";
             } else {
                 return "long";
             }
         } else {
             if(number.doubleValue() < Float.MAX_VALUE) {
                 return "float";
             } else {
                 return "double";
             }
         }
    }
私有静态字符串getDataType(字符串输入){
试一试{
返回getJsonObjectType(输入);
}捕获(JSONException ex1){
试一试{
返回getJsonArrayType(输入);
}捕获(JSONException ex2){
返回getNonJsonType(输入);
}
}
}
私有静态字符串getJsonArrayType(字符串输入)抛出JSONException{
新JSONArray(输入);
返回“JSONArray”;
}
私有静态字符串getJsonObjectType(字符串输入)抛出JSONException{
新的JSONObject((字符串)输入);
返回“JSONObject”;
}
私有静态字符串getNonJsonType(字符串输入){
试一试{
返回getNumberType(输入);
}捕获(解析异常ex3){
返回“字符串”;
}
}
私有静态字符串getNumberType(字符串输入)引发异常{
Number=NumberFormat.getInstance().parse(输入);
如果(长的实例数){
if(number.longValue()
老实说,我不喜欢通过解析器的异常来确定类型的想法。我将为每种格式构建一个模式,并对所有格式进行迭代,以检查给定的字符串是否与其中一个匹配

类似于
Scanner
类的工作方式,但它相当复杂。很难写出涵盖所有可能情况的正则表达式

但如果准备好正则表达式,则算法很简单:

public class Main {

    private final Map<String, String> patterns = Map.of(
            "Integer", integerPattern()
    );

    public String getDataType(String input) {
        for (Map.Entry<String, String> entry : patterns.entrySet()) {
            if (Pattern.matches(entry.getValue(), input)) {
                return entry.getKey();
            }
        }
        return "Unknown";
    }

}
我很确定你可以用谷歌搜索所有的正则表达式,或者在这里找到它们

但是,如果有一个“更轻”的解决方案,或者您只是不想使用regex方法,该怎么办

通过引入
地图
,您可以混合使用不同的技术:

主类{
私有最终映射谓词=Map.of(
“整数”,这个::isInteger,
“JSON”,这个::isJSON
);
公共字符串getDataType(字符串输入){
for(Map.Entry谓词:谓词.entrySet()){
if(谓词.getValue().test(输入)){
返回谓词.getKey();
}
}
返回“未知”;
}
私有布尔值isJSON(字符串输入){
返回LibraryClass.isJSON(输入);
}
专用布尔isInteger(字符串输入){
试一试{
整数值(输入);
}捕获(数字格式){
返回false;
}
返回true;
}
}

我相信它更具可读性,它降低了嵌套级别,并将不同的逻辑封装在不同的方法中。

我的方法是让框架完成它的工作,并使用它以通用的方式解析输入:

Object obj = new org.json.JSONTokener(input).nextValue();
if (obj instanceof JSONArray)
    return "JSONArray";

if (obj instanceof JSONObject)
    return "JSONObject";

if (obj instanceof Integer)
    return "Integer"
...
可能使用
switch
语句或
Map
而不是一长串
if
结构。并捕获无效JSON输入的
JSONException


也许可以简化为返回
obj.getClass()
obj.getClass().getSimpleName()
,以获得与您现在拥有的功能几乎相同的功能。

其长短是:

  • 在不捕获这些异常的情况下,没有合理的方法来封装这个确切的功能
  • 如果您正在谈论将该方法“数百次”运行,那么它真的不应该成为性能瓶颈。如果是,则对其进行基准测试,找出该方法中的瓶颈所在,然后具体解决这些瓶颈
然而,对于完成来说,在不捕捉异常的情况下,您也可以完成类似的事情-尽管请记住,我没有做任何基准测试,对于您的情况,这些结果可能会更快,也可能不会更快

用于计算某物是否是JSON,但它是一个相当过时的库(最近更新于2010年)

如果您想知道某些东西是否适合特定的int,那么除了关闭NFE
parseInt()
真的没有其他明智的方法了。但是,如果您只想知道某个东西是否是数字,可以使用正则表达式:

str.matches("\\d+"); //Returns true if it's a whole positive number
str.matches("-?\\d+"); //Returns true if it's a whole number
(其他正则表达式很容易在网上计算/找到十进制数、带指数的数字等)

或者您可以对其进行流式处理,并分别检查每个字符:

str.chars().allMatch(c->Character.isDigit(c));

或者,您可能希望使用来自Apache Commons的(
isparsable()
,以及该类上的其他方法)预先结束或替换异常检查。

您是否尝试过instanceof(如果可能的话),这是错误的做法。您不必优化您编写的所有内容。特别是不要过早地使用
String
而不捕获
ClassCastException
。如果您知道它肯定是一个字符串,为什么不将参数设置为字符串呢?成功地将其解析为
浮点值
,并不意味着数字不能是精度更高的
双精度
。pa
str.matches("\\d+"); //Returns true if it's a whole positive number
str.matches("-?\\d+"); //Returns true if it's a whole number
str.chars().allMatch(c->Character.isDigit(c));