我有这样的代码,我喜欢使它适用于byte,short,int,long,float和double:
// IF I past in List<Long> it should return List<Long>.
public static <T extends Number> List<T> noneNegativeInts(List<T> numbers) {
List<T> values = new LinkedList<>();
for (T num : numbers) {
values.add((T) Math.abs(num.doubleValue())); // !! Compiler error here.
}
return values;
}
public static <T extends Number> T abs(T number) {
if(number instanceof Double){
Double val=number.doubleValue();
return (T)(val <= 0.0D) ? 0.0D - val : val;
}
if(number instanceof Float){
Float val=number.floatValue();
return (T)(val <= 0.0F) ? 0.0F - val : val;
}
}
如何更改这些代码?
答案 0 :(得分:1)
问题是没有通用Math.abs
功能。 Math.abs
需要特定类型,例如double
,int
等。因此,您被迫将您的通用类型转换为特定类型,例如double
,并且一旦您完成转换,不能再把它变得通用了。
因此,您可以采用与Number
interface相同的模式,并为每种数字类型创建单独的方法。例如:
public static <T extends Number> List<Integer> nonNegativeInts(List<T> numbers) {
// ...
}
public static <T extends Number> List<Double> nonNegativeDoubles(List<T> numbers) {
// ...
}
// etc.
答案 1 :(得分:1)
尝试使用upper bounded wildcard,如此:
import java.util.Arrays;
import java.util.List;
import java.util.LinkedList;
public class A {
public static List<? extends Number> noneNegativeInts(List<? extends Number> numbers) {
List<Number> values = new LinkedList<>();
for (Number num : numbers) {
values.add(Math.abs(num.doubleValue()));
}
return values;
}
public static void main(String[] args) {
System.out.println(noneNegativeInts(Arrays.asList(new Integer[] {2,3,4,5,-1})));
System.out.println(noneNegativeInts(Arrays.asList(new Double[] {2.,3.,4.,5.,-1.})));
System.out.println(noneNegativeInts(Arrays.asList(new Byte[] {2,3,4,5,-1})));
// etc.
}
}
当您想要创建一个可以跨多个Collection类型工作的方法时,上边界通配符非常有用,这些类型的参数化类型与超类相关,例如:List<Integer>
,List<Double>
等。这些类型没有直接的超类,除了通配符,它允许你表达一个&#34;伪超类&#34;所有这些Collection类型基于其参数化类型的超类Number
。然后,您的方法将适用于您指定的边界下存在的任何类。