扩展类的ArrayList迭代

5
我一直在想Java中是否有一个函数可以满足我的需求。我想要遍历一个ArrayList(比如说,这个ArrayList包含了继承自A类的B类和C类对象)。我的意图是仅仅遍历其中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);
    }
}

A:

public class A {

}

B:

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

C:

public class C extends A {

}

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


你需要遍历整个列表,并对列表中的每个对象进行检查,以确定它是否属于你想要的类。你可能需要查看关键字“instance of”,如下面的答案所述...但我担心代码会与你已有的代码相似(但instance of方法更好/更清晰)。 - C.LS
你编辑之前的问题并不清楚你在问什么。 - JRSofty
4个回答

2
您可以为此创建一个可重用的过滤器类,类似于FileFilter。(有关使用guava的方法,请参见korifey的答案。) 除此之外,没有任何现有功能可以完成这项工作。此外,任何现有功能都必须完全按照您正在执行的操作进行,因为List类型没有任何方法可以知道列表中不同类别的对象在哪里。(它也必须遍历它们才能找到它们。)
如果您需要高性能的解决方案,您可以考虑为不同的实例存储单独的列表-取代或者添加到您当前的列表中。您甚至可以将其包装在一个组合类中,通过公共API提供两种功能(所有实例和按类别的实例)。

谢谢回答,我只是好奇,不需要高性能,但也许以后会需要。非常好的回答! - Hidde

2
你可以使用 Guava
就像这样:
for (B b: Iterables.filter(a, B.class)) {
 System.out.println (b.hi);
}

这段代码与 OP 不同:筛选器接受 C 实例,而 OP 仅接受非 C 的 B 实例。然而,OP 可以使用可重用的 Predicate。 - JB Nizet
抱歉,我的错误。如果 C 扩展了 B,而且如果 OP 保持了原始代码,在那里比较类而不是使用 instanceof,则会有所不同。 - JB Nizet

0

我同意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,但是同样的事情。 - Hidde

0

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

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

使用instanceof运算符是一个更好的想法。但是,如果要过滤掉列表中不属于类型B的实例,则需要集成一个额外的集合库,因为标准集合API不直接支持该操作。也许GuavaLambdaJ支持您想要执行的过滤操作,我还没有检查。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接