【问题标题】:letting a java function accept a collection or an array让 java 函数接受集合或数组
【发布时间】:2012-11-28 05:37:36
【问题描述】:

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

我要做的唯一一件事就是对字符串进行循环。现在我最终得到了一个类似于

的尴尬结构
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 接受的类同时允许集合和数组?

【问题讨论】:

    标签: java arrays collections function-declaration


    【解决方案1】:

    Why is an array not assignable to Iterable?

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

    【讨论】:

    • 谢谢,我想我仍然试图让 java 在它的内心深处相信它是 python。
    • 哈哈,这里没有鸭子打字——抱歉。 :)
    • 欢迎来到冗长输入的世界。 Java 基于 WET 原则而不是 DRY 原则(如 Write Everything Twice 而不是 Dont Repeat Yourself)。
    【解决方案2】:

    不幸的是,数组没有实现Iterable,尽管 for-each 循环对两者都有效。

    您只能接受Iterable,因为传递数组有点过时(数组相对于ArrayList 的性能优势可以忽略不计)。使用Arrays.asList(T... a) 可以轻松包装现有数组并转换为List

    【讨论】:

    • 这是一个很好的选择。我在编写的任何新代码中都使用 ArrayLists,但是我继承了很多浮动的数组。
    【解决方案3】:

    虽然数组可以在 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]]
    

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

    【讨论】:

      猜你喜欢
      • 2011-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多