简体   繁体   English

Java泛型:将String []解析为(T扩展Number)[]

[英]Java Generics: parse String[] to (T extends Number)[]

I already have this code implemented, and it works just fine: 我已经实现了此代码,并且可以正常工作:

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

But now I look for something like this: 但是现在我正在寻找这样的东西:

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

Is there any solution for this problem? 这个问题有什么解决办法吗? Didn't find anything. 没有找到任何东西。

T::parseNumber won't work, since there is no parseNumber method in Number . T::parseNumber将不起作用,因为Number没有parseNumber方法。 Furthermore there is no inheritance for static methods. 此外, static方法没有继承。 Also eg BigInteger doesn't even offer a static method for parsing from String and AtomicInteger doesn't offer a constructor that takes String , so even if you use reflection, you won't get it to work with the implementations of Number in the API, let alone all possible implementations... 同样,例如BigInteger甚至不提供用于从String进行解析的static方法,而AtomicInteger不提供采用String的构造函数,因此即使您使用反射,也无法使其与API中Number的实现一起使用,更不用说所有可能的实现了...

T[]::new doesn't work since you cannot generate a array using a type parameter. T[]::new不起作用,因为您不能使用类型参数生成数组。

You could change the method to make it work however: 您可以更改方法以使其起作用,但是:

Pass a Function<String, T> to parse the String s and either pass a IntFunction<T[]> to generate the array or use the Array class ( see How to create a generic array in Java? ): 传递一个Function<String, T>来解析String并传递一个IntFunction<T[]>来生成数组或使用Array类( 请参见如何在Java中创建一个通用数组? ):

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));
}

Sample use 样品使用

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

It cannot work because Number is an abstract class that doesn't provide any generic method allowing to parse a String into the corresponding Number implementation. 它不起作用,因为Number是一个抽象类,它不提供任何允许将String解析为相应的Number实现的通用方法。 You will need to provide your own method as next for example: 接下来,您需要提供自己的方法,例如:

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: This generic parser is not meant to be perfect, it just shows the idea. 注意:这个通用解析器并不意味着是完美的,它只是说明了这个想法。

Then your method will be: 然后您的方法将是:

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));
}

You will then be able to parse your array of String generically as next: 然后,您将可以大致解析出String数组,如下所示:

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

Output: 输出:

1
2
3

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM