在Java中迭代任何类型的泛型数组

在Java中迭代任何类型的泛型数组,java,generics,loops,Java,Generics,Loops,如果有一个Java集合实例可能包含基元类型、泛型数组和/或iterable集合,我想将泛型数组视为iterable集合,但是如何处理呢?e、 g.以下伪java代码 List<?> list1; list1.add(new int[2]); list1.add(new String[3]); list1.add(new ArrayList()); for (Object e : list1){ if (e instanceof Iterable){ /

如果有一个Java集合实例可能包含基元类型、泛型数组和/或iterable集合,我想将泛型数组视为iterable集合,但是如何处理呢?e、 g.以下伪java代码

List<?> list1; 
list1.add(new int[2]); 
list1.add(new String[3]); 
list1.add(new ArrayList());
for (Object e : list1){
    if (e instanceof Iterable){ 
        //The int[2] and String[3] will not fall in this case that I want it be
        //Iterate within e
    }
}
列表列表1;
列表1.添加(新整数[2]);
列表1.add(新字符串[3]);
添加(新的ArrayList());
对于(对象e:list1){
如果(e Iterable的instanceof){
//在这种情况下,int[2]和字符串[3]不会像我希望的那样下降
//在e中迭代
}
}
请建议如何使int[2]和String[3]落在案例中

谢谢和问候,
William

在循环中,可以为
实例
使用适当的数组操作数

对于
int[]

if (e instanceof int[]) {
   // ...
}
if (e instanceof Object[]){
    // ...
}
对于
对象
数组(包括
字符串[]
):

或者,在将阵列添加到主
列表中时,可以将每个阵列都封装在中。在这种情况下,您可以使用
List
generic而不是通配符generic
List
,并避免使用
instanceof
检查数据类型。大概是这样的:

List<List> list1; 
list1.add(Arrays.asList(new int[2])); 
list1.add(Arrays.asList(new String[3])); 
list1.add(new ArrayList());
for (List e : list1){
    // no need to check instanceof Iterable because we guarantee it's a List
    for (Object object : e) {
        // ...
    }
}
列表列表1;
list1.add(Arrays.asList(newint[2]);
list1.add(Arrays.asList(新字符串[3]);
添加(新的ArrayList());
对于(列表e:列表1){
//不需要检查Iterable的instanceof,因为我们保证它是一个列表
用于(对象:e){
// ...
}
}

每当您将
instanceof
和泛型一起使用时,都会感觉到您可能在泛型上做了一些不太正确的事情。

数组没有实现Iterable接口

public class StackOverflow
{
    public static void main(final String[] argv)
    {
        display(new int[0].getClass());
    }

    private static void display(final Class clazz)
    {
        final Class   superClass;
        final Class[] interfaces;

        superClass = clazz.getSuperclass();

        if(superClass != null)
        {
            display(superClass);
        }

        System.out.println(clazz.getCanonicalName());
        interfaces = clazz.getInterfaces();

        for(final Class iface : interfaces)
        {
            display(iface);
        }
    }
}
输出:

java.lang.Object
int[]
java.lang.Cloneable
java.io.Serializable
您可以在类上使用
isArray()
,查看它是否为数组:

public class StackOverflow
{
    public static void main(final String[] argv)
    {
        List<Object> list1;

        list1 = new ArrayList<Object>();
        list1.add(new int[2]);
        list1.add(new String[3]);
        list1.add(new ArrayList());

        for(Object e : list1)
        {
            if(e instanceof Iterable)
            {
                System.out.println("Iterable");
            }

            if(e.getClass().isArray())
            {
                System.out.println("array");
            }
        }
    }
}
公共类堆栈溢出
{
公共静态void main(最终字符串[]argv)
{
清单1;
list1=新的ArrayList();
列表1.添加(新整数[2]);
列表1.add(新字符串[3]);
添加(新的ArrayList());
对于(对象e:list1)
{
if(e Iterable的instanceof)
{
System.out.println(“Iterable”);
}
if(如getClass().isArray())
{
System.out.println(“数组”);
}
}
}
}

使用反射包中的数组类:

    final List<Object> list = new ArrayList<Object>();
    list.add(new int[] { 1, 2 });
    list.add(new String[] { "a", "b", "c" });
    final List<String> arrayList = new ArrayList<String>();
    arrayList.add("el1");
    list.add(arrayList);

    for (Object element : list) {
        if (element instanceof Iterable) {
            for (Object objectInIterable : (Iterable) element) {
                System.out.println(objectInIterable);
            }
        }
        if (element.getClass().isArray()) {
            for (int i = 0; i < Array.getLength(element); i++) {
                System.out.println(Array.get(element, i));
            }
        }
    }
final List=new ArrayList();
添加(新的int[]{1,2});
添加(新字符串[]{“a”、“b”、“c”});
最终列表arrayList=新的arrayList();
arrayList.添加(“el1”);
添加(arrayList);
for(对象元素:列表){
if(Iterable的元素实例){
for(objectobjectinitable:(Iterable)元素){
系统输出打印项次(可对象化);
}
}
if(element.getClass().isArray()){
for(int i=0;i
您不能将内容添加到
列表中。如果您想要异类事物的列表,请使用
列表

但是,既然您想迭代列表中的内容,为什么不使用
列表
?要添加数组,请使用
Arrays.asList(myarray)
从中获取实现
Iterable
的内容

final List<Iterable<? extends Object>> list1 = new ArrayList<Iterable<? extends Object>>();

list1.add(Arrays.asList(new int[2]));
list1.add(Arrays.asList(new String[3])); 
list1.add(new ArrayList<Integer>());

for (final Iterable<? extends Object> e : list1) {
    for (final Object i : e) {
        // ...
    }
}
最终列表使用泛型

public void printArray(T[] someArray) {
    for (T t : someArray)
        System.out.println(t);        
}

是否可以执行类似于“T[]的e instanceof”这样的操作,其中T是类型参数?@William Choi:不,这是不可能的,因为类型擦除
instanceof
发生在运行时,并且
T[]
在编译后丢失。明白了。我误解了T[]将在运行时保留。如果您需要对这些项进行迭代,请使用
列表,而不是
列表。这样,您就可以灵活地存储其他易懂的东西,如
Set
。是的,我们不能将元素添加到列表中。但我们可以在方法参数中使用列表。我只是想说明一下这种情况,抱歉搞混了。回到问题上来,我真的很好奇是否有一种方法可以像“T[]的e instanceof”这样做,其中“T”是类型参数。@William Choi,不,你不能这样做,因为类型参数T只在编译时存在;在运行时,它实际上只是一个对象。如果在运行时需要知道参数化类型,可以让调用方传入
Class
类型的参数。编译器将强制只能传递正确的类对象,并且您可以在类对象上使用类似于
isInstance()
isArray()
、和
getComponentType()
的方法。我可能错了(我经常错),但我认为我提供了一个答案,您可以在不知道确切类型的情况下迭代泛型集合。@Petro Semeniuk:您的解决方案是有效的,但它使数组成为一种特殊情况,并以不同的方式处理它们。最初问题的精神(至少在我的解释中)是我们如何避免这样做。“我们怎样才能使数组的行为与我们的其他Iterables一样,而不单独处理它们呢?”Asah。谢谢我真的误解了原来的问题。将数组包装到集合中确实是最好的解决方案。干杯
public void printArray(T[] someArray) {
    for (T t : someArray)
        System.out.println(t);        
}