通常的类里面的通用静态方法;使用基本类型的数组

时间:2018-02-07 09:24:43

标签: java arrays generics

我有一个班级Test和一个方法testMethod。我尝试将int和类型为T的数组传递给该方法,它应该返回数组的int'元素。

public class Test  {
    public static void main(String[] args)  {
        System.out.println(testMethod(1, new int[] {1,2,4}));
    }

    public static <T> T testMethod(int rank, T[] elements)  {
        return elements[rank];
    }
}

但是我得到_method testMethodin class Test cannot be applied to given types_T extends Object declared in method <T>testMethod(int,T[])

我想问题是数组是基本类型int。我尝试将其更改为Integer并且有效。

有没有办法让它工作,同时仍然使用基本数字类型,如intdoublefloat

4 个答案:

答案 0 :(得分:4)

您必须重载testMethod(int, T[])方法才能传递int[]数组:

public static int testMethod(int rank, int[] elements) {
    return elements[rank];
}

否则,您需要满足T[]T extends Object(拒绝基本类型)的要求并传递Integer[]数组:

public static <T> T testMethod(int rank, T[] elements)  {
    return elements[rank];
}

现在您可以传递int[]Integer[]

final Integer i1 = testMethod(1, new Integer[]{1, 2, 4});
final int i2 = testMethod(1, new int[]{1, 2, 4});
  

有没有办法让它工作,同时仍然使用基本的数字类型,如int或double或float?

不幸的是,只能通过方法重载。看看Arrays.binarySearch方法(那里有18个不同的签名)。大多数签名的设计仅涵盖所有类型。

  

重载是否只需要从主函数复制代码?

我很害怕,是的(小型和命名更改)。找出差异:)

public static void parallelSort(long[] a, int fromIndex, int toIndex) {
    rangeCheck(a.length, fromIndex, toIndex);
    int n = toIndex - fromIndex, p, g;
    if (n <= MIN_ARRAY_SORT_GRAN ||
        (p = ForkJoinPool.getCommonPoolParallelism()) == 1)
        DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0);
    else
        new ArraysParallelSortHelpers.FJLong.Sorter
            (null, a, new long[n], fromIndex, n, 0,
             ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ?
             MIN_ARRAY_SORT_GRAN : g).invoke();
}

public static void parallelSort(float[] a, int fromIndex, int toIndex) {
    rangeCheck(a.length, fromIndex, toIndex);
    int n = toIndex - fromIndex, p, g;
    if (n <= MIN_ARRAY_SORT_GRAN ||
        (p = ForkJoinPool.getCommonPoolParallelism()) == 1)
        DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0);  // 1
    else
        new ArraysParallelSortHelpers.FJFloat.Sorter                     // 2
            (null, a, new float[n], fromIndex, n, 0,                     // 3
             ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ?
             MIN_ARRAY_SORT_GRAN : g).invoke();
}
  

将这些代码稍加修改的粘贴复制到多个函数中是不错的做法?

绝对不是。但我们还有另一种方式吗?

你可以说原始拳击可能是一个选择:

final int[] ints = {1, 2, 4};
final Integer i3 = testMethod(1, Arrays.stream(ints).boxed().toArray(Integer[]::new));

一个好的API 会强制用户转换他们的数据以适应给定的签名吗?

答案 1 :(得分:1)

您不能使用基本类型代替泛型类型参数。

您可以改为传递Integer数组:

System.out.println(testMethod(1, new Integer[] {1,2,4}));

答案 2 :(得分:1)

您不能在Generic类型中使用原语,因为这不是继承Object。在Why don't Java Generics support primitive types? 中查看更多相关信息。要在您的情况下转换为Integer数组,您可以使用Streamn API执行装箱:

public static Integer[] boxed(int[] array){
    return IntStream.of(array).boxed().toArray(Integer[]::new);
}

它基本上与迭代数组并将值装入另一个实例相同。

每次要在泛型方法中使用原始数组时都需要这样做...不完美但这样可以转换每个现有数组而无需更改现有变量的类型({{ 1}}可以Integer添加其他问题。)

null

编辑:

无需更改通话,只需覆盖原始int[] array = {1,2,4}; System.out.println(testMethod(1, boxed(array))); 的方法:

int

注意:对于某些类型,您可能会被迫简单地使用循环构建数组...这将更加冗长。

答案 3 :(得分:0)

我认为你已经提到了使这段代码在你的问题中起作用的解决方案..我们唯一的就是我们必须使用Integer而不是int ..

public static void main(String[] args)  {
    System.out.println(testMethod(1, new Integer[] {1,2,4}));
}

public static <T> T testMethod(int rank, T[] elements)  {
    return elements[rank];
}

如果你想使用int,你不能使用T []而必须使用int []而不是..