在Java中是否有一个参数可以用于all for each循环?
假设我有一个方法,它接受一个数组,并使用Java的内置函数处理其中的每个元素,如下所示:在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
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对象,无论是基元数组还是集合。我可以很容易地编写两个方法,一个包装另一个,但我只是好奇是否有更好的方法。”。“好吧,那我对这个问题读得不够好。我希望这一个更好。是的,真的没有其他答案。所有的“答案”都只是权宜之计或建议。