在Java中是否有一个参数可以用于all for each循环?

在Java中是否有一个参数可以用于all for each循环?,java,iterator,foreach,Java,Iterator,Foreach,假设我有一个方法,它接受一个数组,并使用Java的内置函数处理其中的每个元素,如下所示: public static void myFun(SomeClass[] arr) { for (SomeClass sc : arr) { // Stuff is processed here } } List<? extends MyCrustaceans> seaLife = new ArrayList<? extends MyCrustaceans

假设我有一个方法,它接受一个数组,并使用Java的内置函数处理其中的每个元素,如下所示:

public static void myFun(SomeClass[] arr) {
    for (SomeClass sc : arr) {
        // Stuff is processed here
    }
}
List<? extends MyCrustaceans> seaLife = new ArrayList<? extends MyCrustaceans>();
MyShrimp s = new MyShrimp("bubba");
seaLife.add(s);
DoStuff(seaLife);

...

public static void DoStuff(List<? extends MyCrustaceans> seaLife)
{
    for (MyCrustaceans c : seaLife) {
        System.out.println(c);
    }
}
这很好,但现在我希望能够将相同的方法传递给一个
列表
。我是注定要使用的,还是有一个参数可以用于
myFun()
,它接受可以在for-each构造中使用的任何类型


澄清一下:我想要一个方法签名,它将接受任何iterable对象,无论是基元数组还是集合。我可以很容易地编写两个方法,一个包装另一个,但我只是好奇是否有更好的方法。

使用。这就是它的目的

正如您所说,它不会处理数组

您不希望使用多个相互包装的方法。这排除了
array.asList
Collection.toArray

所以你的问题的答案是不,没有办法。但是如果您可以使用
列表
,为什么要使用数组呢

在这里,我仍然会使用
Iterable
。我喜欢它胜过
Collection
,因为在过去,我有一些类实现了
Iterable
,但不是Collection;这使得它们可以轻松地根据需要懒洋洋地检索值,我可以在它们上使用foreach循环。

publicstaticvoidmyfun(Collection){
public static void myFun(Collection<MyClass> collection) {
    for (MyClass mc : collection) {
        // Stuff is processed here
    }
}
对于(MyClass mc:集合){ //东西在这里加工 } }
我建议使用
Iterable
Collection
List
作为参数类型

在IMO中,集合应该优先于引用数组。如果您碰巧有一个数组
Arrays.asList
可以很好地进行转换<代码>数组。asList允许获取和设置返回到数组,但显然不允许“结构性”修改,这会改变数组长度

myFun(Arrays.asList(arr));
在极端/一般情况下,可能必须使用通配符

public static void myFun(Iterable<? extends SomeClass> somethings) {
    for (SomeClass something : somethings) {
        // something is processed here
    }
}

publicstaticvoidmyfun(Iterable您不能,java数组不实现Iterable:

public static int sum(Iterable<Integer> elements) {
    int s = 0;

    for (int i : elements) {
        s += i;
    }

    return s;
}

public static void main(String[] args) {
    L1: System.out.println(sum(1,2,3));
    L2: System.out.println(sum(Arrays.asList(1,2,3)));
    L3: System.out.println(sum(new int[] { 1,2,3 }));
}
public静态整数和(Iterable元素){
int s=0;
for(int i:元素){
s+=i;
}
返回s;
}
公共静态void main(字符串[]args){
L1:System.out.println(和(1,2,3));
L2:System.out.println(和(数组.asList(1,2,3));
L3:System.out.println(sum(新的int[]{1,2,3}));
}
这将导致(L1和L3)中的两个编译时错误;因此必须设计 方法要接受Iterable(集合)和/或数组,至少必须有一个方法执行某些转换(到/从数组)

解决方法

您可以尝试使用适配器:

public class ArrayIterator<T> implements Iterator<T> {

    private final T[] array;
    private int i;

    public ArrayIterator(T[] anArray) {
        array = anArray;
        i = 0;
    }

    public boolean hasNext() {
        return i < array.length;
    }

    public T next() {
        return array[i++];
    }

    public void remove() {
        throw new UnsupportedOperationException();
    }
}

private static int sum(final Integer ... elements) {
    return sum(new Iterable<Integer>() {

        public Iterator<Integer> iterator() {
            return new ArrayIterator<Integer>(elements);
        }
    });
}
公共类ArrayIterator实现迭代器{
私有final T[]数组;
私人互联网i;
公共阵列计数器(T[]阵列){
数组=数组;
i=0;
}
公共布尔hasNext(){
返回i
只有在处理基元数组时才应注意;如果仅使用 引用对象(您的案例)ArrayIterator+匿名类很酷


希望对您有所帮助。

Java 1.5+中的Java泛型有一个鲜为人知的特性,您可以在其中使用
简短的回答:不,没有一个方法签名可以安全地同时接受Iterable和array。显然,您可以只接受
对象,但这也是一种攻击

冗长的回答:由于增强的
for
-循环被有效地定义了两次(一次用于数组,一次用于
Iterable
),因此您还需要提供两种重载方法:

public static void myFun(SomeClass[] array) {
    for (SomeClass sc : array) {
        doTheProcessing(sc);
    }
}

public static void myFun(Iterable<? extends SomeClass> iterable) {
    for (SomeClass sc : iterable) {
        doTheProcessing(sc);
    }
}
publicstaticvoidmyfun(SomeClass[]数组){
用于(SomeClass sc:array){
doTheProcessing(sc);
}
}

公共静态无效myFun(IterableIf您使用Iterable作为参数,那么当您尝试传入基本数组时,您会出现编译错误。嗯,我猜这与OO有关。您不需要在数组周围编写包装器吗?我同意;对于这种情况,我使用Iterable,因为它对实现者施加的负担最小。虽然它不适用于Object[]直接来说,将其与Arrays.asList()连接起来是很简单的。是的。OTOH,可以想象实现在迭代之前需要集合大小,并且大多数代码仍然使用集合。鉴于似乎没有办法避免asList()或toArray(),我最同意这种逻辑;使用Iterable而不是Object[]是有意义的如果我希望两者都有输入(添加了一段关于asList和toArray的内容),不幸的是答案是否定的,因为数组没有实现Iterable。“澄清一下:我想要一个方法签名,可以接受任何iterable对象,无论是基元数组还是集合。我可以很容易地编写两个方法,一个包装另一个,但我只是好奇是否有更好的方法。”。“好吧,那我对这个问题读得不够好。我希望这一个更好。是的,真的没有其他答案。所有的“答案”都只是权宜之计或建议。