我编写了以下代码来确定用户输入的输入的数据类型.
更新:删除解析,Float因为Double也可以Float按照@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";
}
}
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我要反复运行数百次,而且我读过捕捉Exception是一项昂贵的操作.
有没有更好的方法来实现这一目标?
我的方法是让框架做它的事情,并用它来解析输入的通用方式:
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"
...
Run Code Online (Sandbox Code Playgroud)
也许使用switch语句或Map代替一长串if构造.并捕获JSONException无效JSON的输入.
也许可以简化为返回obj.getClass()或obj.getClass().getSimpleName()几乎相同的功能,你现在拥有.
老实说,我不喜欢通过解析器的异常来确定类型的想法.我将为每种格式构建一个模式,并迭代所有格式以检查给定的字符串是否匹配其中一个.
这与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";
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个有趣的部分 - 一个例子integerPattern().我已经取消了它Scanner并简化了一下:
private String integerPattern() {
String radixDigits = "0123456789abcdefghijklmnopqrstuvwxyz".substring(0, 10);
String digit = "((?i)[" + radixDigits + "]|\\p{javaDigit})";
String groupedNumeral = "(" + "[\\p{javaDigit}&&[^0]]" + digit + "?" + digit + "?(" +
"\\," + digit + digit + digit + ")+)";
String numeral = "((" + digit + "++)|" + groupedNumeral + ")";
String javaStyleInteger = "([-+]?(" + numeral + "))";
String negativeInteger = "\\-" + numeral + "";
String positiveInteger = "" + numeral + "";
return "(" + javaStyleInteger + ")|(" +
positiveInteger + ")|(" +
negativeInteger + ")";
}
Run Code Online (Sandbox Code Playgroud)
我很确定你可以谷歌所有的正则表达式或在这里找到它们.
但是,如果有一个"更轻"的解决方案或者您根本不想使用正则表达式方法呢?
您可以通过以下方式混合使用不同的技术Map<String, Predicate<String>>:
class Main {
private final Map<String, Predicate<String>> predicates = Map.of(
"Integer", this::isInteger,
"JSON", this::isJSON
);
public String getDataType(String input) {
for (Map.Entry<String, Predicate<String>> predicate : predicates.entrySet()) {
if (predicate.getValue().test(input)) {
return predicate.getKey();
}
}
return "Unknown";
}
private boolean isJSON(String input) {
return LibraryClass.isJSON(input);
}
private boolean isInteger(String input) {
try {
Integer.valueOf(input);
} catch (NumberFormatException e) {
return false;
}
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
我相信它更具可读性,它降低了嵌套级别,并在不同的方法中封装了不同的逻辑.
| 归档时间: |
|
| 查看次数: |
491 次 |
| 最近记录: |