12

我正在尝试编写一个函数,该函数需要一些字符串并对其进行处理。

我要做的唯一一件事就是对字符串进行循环。现在我最终得到了一个尴尬的结构

public void foo(String[] myStrings){
    foo(java.util.Arrays.asList(myStrings));
}

public void foo(Iterable<String> myStrings){
    for(String i : myStrings){
        bar(i);
    }
}

感觉多余,因为

for(String i : myStrings){
    bar(i);
}

对于 String[] 类型的 myStrings 来说,这将是完全有效的代码。

是否有一个我可以让 foo 接受的类同时允许集合和数组?

4

3 回答 3

11

请参阅为什么数组不能分配给 Iterable?

简短的回答:没有。据我了解,数组类型是合成代码,因此不实现Iterable或任何其他类型。您需要提供重载方法或要求客户端在Arrays.asList调用点调用。

于 2012-12-10T18:48:30.953 回答
3

不幸的是 array 没有实现Iterable,尽管 for-each 循环在两者上都有效。

您只能接受Iterable,因为传递数组有点过时(数组的性能优势ArrayList可以忽略不计)。现有数组可以很容易地包装并转换为Listusing Arrays.asList(T... a)

于 2012-12-10T18:48:46.360 回答
2

尽管数组可以在 for-each 循环中使用,但它们不实现Iterable. 只有两种可能性,要么重载你所说的方法,要么只提供可迭代的变体并强制客户端调用Arrays.asList().

如果您还想提供数组重载,您可以将其签名从简单数组更改为可变参数:

public void foo(String... myStrings){
    foo(java.util.Arrays.asList(myStrings));
}

在这种情况下,请注意原始数组和原始包装数组之间的不兼容:

static void foo(int... ints) {}
foo(new Integer[] {1, 2}); // compile error

和:

static void foo(Integer... integers) {}
foo(new int[] { 1, 2 }); // compile error

最晦涩的部分,带有通用可变参数:

static <T> T[] foo(T... ts) {
    return ts;
}

如果您传递一个整数数组:

Integer[] integers = { 1, 2 };
System.out.println(Arrays.deepToString(foo(integers)));
> [1, 2]

的值ts是具有 2 个元素的整数数组:12

然而,如果你传递一个原始整数数组,就会发生一件有趣的事情:

int[] ints = { 1, 2 };
System.out.println(Arrays.deepToString(foo(ints)));
> [[1, 2]]

int[][]在这种情况下,ts 的值是一个只有一个元素的 int 数组 ( ) 数组,也就是最初传递的数组。这样做的原因是 anint不是一个Object(自动装箱在这里没有帮助),而一个 int 数组是,所以T类型参数的值变成int[].

于 2012-12-10T19:04:52.797 回答