我遇到一种情况,我会得到一个字符串,我需要确定Class<?>
最适合它的值,给出以下约束:
"true"
或"false"
,则它是Boolean
Integer
Double
YYYY-MM-DD hh:mm:ss.sss
匹配,则其为Java Date
String
afterall 我最好的尝试是讨厌的,涉及很多嵌套的try/catch
块:
// Groovy pseudo-code
Class<?> determineValueType(String value) {
Class<?> clazz
if(value.equalsIgnoreCase('true') || value.equalsIgnoreCase('false')) {
clazz = Boolean
} else {
try {
Integer.parse(value)
clazz = Integer
} catch(Exception ex1) {
try {
Double.parse(value)
clazz = Double
} catch(Exception ex2) {
try {
Date.parse('YYYY-MM-DD hh:mm:ss.sss', value)
clazz = Date
} catch(Exception ex3) {
clazz = String
}
}
}
}
clazz
}
是否有任何 Groovier 方法可以实现这一点,也许某些晦涩的Groovy反射API特有的东西?
答案 0 :(得分:4)
有两种方法可以帮助您在Groovy的扩展String类(实际上在CharSequence
上):
但是对于其他情况,AFAIK,您可以自己实现解析。您可以尝试使用地图和一些闭包来减少一些样板:
Class parse(val) {
def convert = [
(Integer) : { it.toInteger() },
(Double) : { it.toDouble() },
(Date) : { Date.parse('YYYY-MM-DD hh:mm:ss.sss', it) },
(Boolean) : { Boolean.parseBoolean it },
(String) : { it }
]
convert.findResult { key, value ->
try {
if (value(val)) return key
} catch (e) {}
}
}
assert parse('9.1') == Double
assert parse('9') == Integer
assert parse('1985-10-26 01:22:00.000') == Date // great scott!
assert parse('chicken') == String
assert parse('True') == Boolean
请注意,如果(Double)
位于(Integer)
之前,则测试将无效,因为9
既是双精度又是整数。
答案 1 :(得分:3)
Groovy有一些功能可以让你使这个逻辑更加灵活。
isInteger
和isDouble
内置CharSequence方法。可悲的是,没有严格的isBoolean
因此我们需要自己实施。结合这些功能......
Class<?> determineValueType(String value) {
switch (value) {
case { ['true', 'false'].contains(value?.toLowerCase()) }:
return Boolean
case { value?.isInteger() }:
return Integer
case { value?.isDouble() }:
return Double
case ~/^\d{4}-\d{2}-\d{2} \d{1,2}:\d{2}:\d{2}\.\d{3}$/:
return Date
default:
return String
}
}
assert determineValueType('true') == Boolean
assert determineValueType('false') == Boolean
assert determineValueType('2039230') == Integer
assert determineValueType('203923.0') == Double
assert determineValueType('2016-07-26 12:00:00.000') == Date
assert determineValueType('foo') == String
我使用正则表达式而不是SimpleDateFormat来避免必须捕获异常。它可能具有稍微不同的语义,但您也可以创建一个辅助方法,如果Date.parse
抛出异常,则返回false。