我正在尝试创建一个泛型函数,该函数基于一个字符串构建任何类型的List,该字符串包含由逗号分隔的那种类型的值。我这样做了:
public static <T> List<T> stringToList(String listStr, Class<T> itemType)
{
return Arrays.asList(listStr.split(",")).stream().map(x -> itemType.cast(x.replaceAll("\\s+|\"|\t","")))).collect(Collectors.toList());
}
当我尝试用以下方法测试时:
String listStringsStr = "\"Foo\", \"Bar\"";
List<String> resS = stringToList(listStringsStr, String.class);
String listIntegersStr = "1,10,-1,0";
List<Integer> resI = stringToList(listStringsStr, Integer.class);
我有两个问题。
java.lang.ClassCastException: Cannot cast java.lang.String to java.lang.Integer
,这意味着它无法转换&#34; 1&#34;我知道这适用于Integer::parseInt
,但我想制作一个通用的方法。任何想法?
[编辑] - 因为我发布它的方式引起了混乱,我添加了测试代码:
String listStringsStr = "\"Foo\", \"Bar\"";
List<String> listStrings = Arrays.asList("Foo", "Bar");
String listIntegersStr = "1,10,-1,0";
List<Integer> listIntegers = Arrays.asList(1, 10, -1, 0);
List<String> resS = stringToList(listStringsStr, String.class);
System.out.println(resS);
System.out.println(listStrings);
assert (resS.containsAll(listStrings));
List<Integer> resI = stringToList(listIntegersStr, Integer.class);
System.out.println(resI);
System.out.println(listIntegers);
assert (resI.containsAll(listIntegers));
包含x.replaceAll("\\s+|\"|\t","")
第一个断言现在通过后,第二个断言失败。控制台输出
[Foo, Bar]
[Foo, Bar]
[1, 10, -1, 0]
[1, 10, -1, 0]
listIntegers持有Integer因此我认为resI持有整数,或者我刚刚打破了java的类型安全性:D
答案 0 :(得分:6)
对于问题#2:一个简单的修改是传递Function<String, T>
而不是Class<T>
。该函数将定义如何将字符串解析为所需类型的类。一些可能的值:
Function<String, String> stringParser = s -> s;
Function<String, Integer> intParser = s -> Integer.parseInt(s);
对于问题#1:在示例中,您给出了输入字符串 do 包含引号。您可以创建输入字符串"Foo,Bar"
以避免在输出中使用引号。如果您无法控制输入,则可以修剪引号/空格/等。作为解析函数的一部分,或者通过比逗号分割更高级的东西来分隔单词 - 是输入CSV文件吗?