Java Generics:解析String []到(T extends Number)[]

时间:2016-06-18 08:10:23

标签: java generics

我已经实现了这个代码,它运行得很好:

static Integer[] parseInteger(String[] arr){
     return Arrays.stream(arr).map(Integer::parseInt).toArray(Integer[]::new);
}

但现在我想找到这样的东西:

public <T extends Number> T[] parseString(String[] arr,T n, Class<T> type){
    return Arrays.stream(arr).map(T::parseNumber).toArray(T[]::new);
}

这个问题有解决办法吗?没找到任何东西。

2 个答案:

答案 0 :(得分:2)

T::parseNumber无法使用,因为parseNumber中没有Number方法。此外,static方法没有继承。例如, BigInteger甚至没有提供static方法来解析StringAtomicInteger不提供带String的构造函数,所以即使你使用反思,你不会让它在API中使用Number的实现,更不用说所有可能的实现......

T[]::new不起作用,因为您无法使用类型参数生成数组。

您可以更改方法以使其正常工作:

传递Function<String, T>来解析String并传递IntFunction<T[]>以生成数组或使用Array类(see How to create a generic array in Java?):< / p>

public <T extends Number> T[] parseString(String[] arr, Function<String, T> parser, Class<T> type){
    return Arrays.stream(arr).map(parser).toArray(size -> (T[]) Array.newInstance(type, size));
}

使用示例

parseString(new String[]{ "1", "10", "193593118746464111646135179395251592"}, BigInteger::new, BigInteger.class)

答案 1 :(得分:1)

它无法工作,因为Number是一个抽象类,它不提供允许将String解析为相应Number实现的任何通用方法。您将需要提供自己的方法,例如:

public class NumberParser {
    public static <T extends Number> T parseNumber(String val, Class<T> type) {
        if (type == Double.class) {
            return (T) Double.valueOf(val);
        } else if (type == Float.class) {
            return (T) Float.valueOf(val);
        } else if (type == Integer.class) {
            return (T) Integer.valueOf(val);
        } else if (type == Long.class) {
            return (T) Long.valueOf(val);
        }
        throw new IllegalArgumentException("Unknown number type");
    }
}

NB:这个通用解析器并不是完美的,它只是表明了这个想法。

然后你的方法将是:

public static <T extends Number> T[] parseString(String[] arr, Class<T> type){
    return Arrays.stream(arr).map(s -> NumberParser.parseNumber(s, type))
        .toArray(length ->  (T[]) Array.newInstance(type, length));
}

然后,您将能够将String的数组一般地解析为下一个:

String[] values = {"1", "2", "3"};
Integer[] result = parseString(values, Integer.class);
for(Integer i : result) {
    System.out.println(i);
}

<强>输出:

1
2
3