方法重载技术



我有一个方法重载,如下所示:

public class Odddetector {
public static void main(String[] args) {
int count = countOdd(new int [] {5, 7, 3, 9, 0});
System.out.println(count);
count = countOdd(new int [] {2, 6, 4, 8, 1});
System.out.println(count);
count = countOdd(5, 7, 10);
System.out.println(count);
count = countOdd(8, 2, 7);
System.out.println(count);
count = countOdd(new int[][] {{1, 2}, {3, 4, 5}});//extra point only
System.out.println(count);
count = countOdd(new int[][] {{6, 2}, {3, 4, 0}});//extra point only
System.out.println(count);
}
public static int countOdd(int[] a){
int count=0;
for (int i: a) count = (i %2 != 0)?++count:count;
return count;
// Do Something;
}
public static int countOdd(int[][] a){
// Do Something;
int count=0;
for (int b = 0; b< a.length; b++){
//System.out.println(java.util.Arrays.toString(a[b])); not a necessary line.
count += countOdd(a[b]);
}
return count;
}
// more method overloading

我的问题是有一种方法可以将解决方案压缩为一个考虑到n维数组的方法。代码像这样运行得很好,但是,我想知道哪些Java技术可以帮助解释维度的增加。我想添加一些细节,那就是第一个方法是基方法,所有其他方法都调用第一个int[] a。我添加的新部分是完整的代码,我目前正在开发这段代码,我的教授给了一个挑战。我目前有Lang编写的数据结构,并且可以接受提示。实际上我更喜欢提示,因为我想学习编写这个。

当参数是多维数组时,您可以递归地调用向下挖掘的函数,直到最终得到一个一维数字数组。逻辑是:

if a is a multi-dimensional array
for each array in a
call recursively
else
count odd numbers in a

我有两个函数。一个接受可变数量的参数,另一个是递归参数。第一个函数只是用var参数作为数组调用第二个函数。如果您想允许混合参数(例如:countOdd(new int [] {1,2,3}, 4, 5);)

,则varargs函数需要做一些工作。
// The var args version. You call this. It then calls the recursive
// version.
public static <T> int countOdd(T... arguments)
{
return countOddRec(arguments);
}
// Recursive version
private static <T> int countOddRec(T[] a)
{
if (a == null || a.length == 0) return 0;

int count=0;
// Is it an array of Numbers?
if (a[0] instanceof Number) {
for (T i: a) {
// Simplified the counting code a bit. Any # mod 2 is either 0 or 1
count += ((Number)i).intValue() % 2;
}
}
// Is it an multi-dimensional? Call recursively for each sub-array.
else {
for (T sub : a) {
count += countOddRec((T[])sub);
}
}

return count;
}

正如在注释中提到的,这将不适用于基本数据类型(例如:int等)。相反,请使用非基本类型(例如:Integer等)。

嗯,我想周围有一些非常有趣的问题,它们都结合在一起。即

  1. 如何泛化数组处理和方法声明任意深度(这是你最初的问题)?
  2. 如何深遍历未知深度阵列?
  3. 如何注入一些有用的负载进入数组遍历(在您的情况下-计数奇数)独立于遍历本身?
  4. 是否有可能为原语和对象数组泛化方法,以及如何?

我对第3点有一个很好的建议:而不是在方法本身硬编码有效载荷,我们可以产生IntStream(或Object版本的通用Stream),可以单独处理。

关于第1点和第4点,我猜这可能是不可能的,或者至少是不优雅的。java.lang.reflect.Array对此没有表现出任何惊奇,我的假设是——如果JDK不能做到这一点,我也不能。因此,最好的选择可能是允许使用Object进行一般签名,并伴随着几个经常使用的重载,直到深度3。当然,这意味着ClassCastExceptions在运行时有危险。

因此,实现第2点的最终结果可能是这样的

public class FlattenArray {
public static IntStream flatten(int n) {
return IntStream.of(n);
}
public static IntStream flatten(int[] array) {
return IntStream.of(array);
}
public static IntStream flatten(int[][] array) {
return flatten((Object) array);
}
public static IntStream flatten(Object array) {
Class<?> aClass = array.getClass();
if (!aClass.isArray())
return IntStream.of(((Number) array).intValue());
else {
Class<?> componentType = aClass.getComponentType();
if (componentType.isPrimitive())
return IntStream.of((int[]) array);
else
return Arrays.stream((Object[]) array).flatMapToInt(FlattenArray::flatten);
}
}
}

long count = FlattenArray.flatten(2, 3, 5, 7).filter(i -> i & 1 != 0).count();

最新更新