从String构建List <t>

时间:2016-01-27 17:03:47

标签: java casting java-stream

我正在尝试创建一个泛型函数,该函数基于一个字符串构建任何类型的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);

我有两个问题。

  1. 在第一种情况下(字符串),我在每个字符串项目周围得到一个额外的双引号:&#34;&#34; Foo&#34;&#34;,&#34;&#34; Bar&#34; &#34;
  2. 在第二种情况下(整数),我得到一个java.lang.ClassCastException: Cannot cast java.lang.String to java.lang.Integer,这意味着它无法转换&#34; 1&#34;我知道这适用于Integer::parseInt,但我想制作一个通用的方法。
  3. 任何想法?

    [编辑] - 因为我发布它的方式引起了混乱,我添加了测试代码:

    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

1 个答案:

答案 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文件吗?