【问题标题】:Iterating through Arraylist with extended classes使用扩展类遍历 Arraylist
【发布时间】:2012-01-15 21:31:19
【问题描述】:

我一直想知道 Java 中的一个函数,我希望它存在。我想遍历一个 Arraylist(比如 A 类),它包含 B 类和 C 类的对象,它们都扩展了 A。这个想法,我只想遍历(例如)ArrayList 中 B 类的对象。

这怎么可能,就像下面代码中的简短示例,而没有长示例?

主类:

     import java.util.*;

public class Test {

    public static void main(String[] args) {
        new Test ();
    }

    Test() {
        ArrayList<A> a = new ArrayList<A> ();
        a.add (new B ());
        a.add (new C ());
        a.add (new C ());
        a.add (new B ());
        a.add (new C ());
        for (A aObject : a) { // this works, I want it shorter
            if (aObject instanceof B) {
                B b = (B) aObject;
                System.out.println (b.hi);
            }
        }
        for (B b : a) // like this?
            System.out.println (b.hi);
    }
}

答:

public class A {

}

乙:

public class B extends A {
    String hi = "hi";
}

C:

public class C extends A {

}

编辑:因为很多人回答这个问题:我知道 instanceof 的用法。我想要一种更快的方法来遍历数组中的所有对象,其中类是 B。

【问题讨论】:

  • 您必须遍历所有列表和列表中的每个对象以检查它是否属于您想要的类。您可能想查看下面答案中已经说明的关键“实例”......但我担心代码将与您拥有的代码相似(但方法实例更好/更清洁)跨度>
  • 您编辑之前的问题并不清楚您的要求。

标签: java class iteration


【解决方案1】:

你可以为它创建一个可重用的过滤器类,类似于FileFilter。 (请参阅 korifey 对使用番石榴的回答。)除此之外,不,没有任何现有的功能可以做到这一点。此外,任何现有功能都必须完全按照您正在做的事情做,因为List 类型无法知道不同类别的对象在列表中的位置。 (它也必须遍历它们才能找到它们。)

如果您需要一个高性能的解决方案,您可以考虑为您的单独实例存储单独的列表 - 替代您当前的列表或添加到您的当前列表中。您甚至可以将其封装在一个复合类中,该类将通过一个通用 API 提供两种功能(所有实例和类实例)。

【讨论】:

  • 感谢您的回答,我只是好奇,不需要高性能,但也许我曾经需要它。很好的答案!
【解决方案2】:

您可以使用guava

像这样:

for (B b: Iterables.filter(a, B.class)) {
 System.out.println (b.hi);
}

【讨论】:

  • 这与 OP 做的事情不同:过滤器接受 C 实例,而 OP 只接受不是 C 的 B 实例。不过,OP 可以使用可重用的谓词。跨度>
  • 对不起,我的错误。如果 C 扩展了 B,并且如果 OP 在比较类而不是使用 instanceof 的地方保留其原始代码,那么就会有所不同。
【解决方案3】:

我同意 JRSofty。

for (A aObject : a) {
    if (aObject instanceof B) { // <-- This is as short I can make it
        B b = (B) aObject;
        System.out.println (b.hi);
    }
}

【讨论】:

  • 我已经展示了那个例子,没有instanceof,但同样的东西。
【解决方案4】:

你可以像这样写一个更简单的循环:

for (A aObject : a)
    if (aObject instanceof B)
        System.out.println(((B) aObject).hi);

最好使用instanceof 运算符。但是为了过滤掉不属于B 类型的列表实例,您需要集成一个额外的集合库,因为标准集合 API 不直接支持该操作。可能Guava 或者LambdaJ 支持你想做的那种过滤操作,我还没查。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-28
    • 2023-03-04
    • 2020-12-27
    • 2016-09-01
    • 2012-12-10
    • 2015-02-13
    • 2015-06-17
    相关资源
    最近更新 更多