我有一个方法重载,如下所示:
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);
)
// 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
等)。
嗯,我想周围有一些非常有趣的问题,它们都结合在一起。即
- 如何泛化数组处理和方法声明任意深度(这是你最初的问题)?
- 如何深遍历未知深度阵列?
- 如何注入一些有用的负载进入数组遍历(在您的情况下-计数奇数)独立于遍历本身?
- 是否有可能为原语和对象数组泛化方法,以及如何?
我对第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();