让java函数接受集合或数组

时间:2012-12-10 18:45:29

标签: java arrays collections function-declaration

我正在尝试编写一个带有一些字符串并对它们做某事的函数。

我要做的唯一事情是字符串集循环遍历它们。现在我最终得到了一个尴尬的构造

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的类,它将允许集合和数组?

3 个答案:

答案 0 :(得分:9)

请参阅Why is an array not assignable to Iterable?

简答:不。根据我的理解,数组类型是合成代码,因此不实现Iterable或任何其他类型。您需要提供重载方法或要求客户在呼叫站点呼叫Arrays.asList

答案 1 :(得分:3)

不幸的是,尽管for-each循环同时工作,但数组并没有实现Iterable

您可以专门接受Iterable,因为传递数组有点旧学校(数组超过ArrayList的性能优势可以忽略不计)。现有数组可以轻松打包并使用Arrays.asList(T... a)转换为List

答案 2 :(得分:2)

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

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

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

最不起眼的部分,使用通用的varargs:

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数组,就会发生一件有趣的事情:

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

在这种情况下,ts的值是一个int数组(int[][])的数组,只有一个元素,它是最初传递的数组。这样做的原因是int不是Object(自动装箱在这里没有帮助),而是一个整数数组,因此{{1}的值} type参数变为T