Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Iterating through Arraylist with extended classes

I have been wondering about a function in Java, which I hope exists. I want to iterate through an Arraylist (say of class A), which contains objects of class B and C which both extend A. The idea, I only want to iterate through (for example) the objects of the B class in the ArrayList.

How is this possible, like the short example in the code below, and without the long one?

The main class:

     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 {

}

EDIT: Because so many people answer this: I know of the use of instanceof. I want a faster way to loop through all the objects in the array, of which the class is B.

like image 616
Hidde Avatar asked Oct 09 '22 06:10

Hidde


2 Answers

You could make a reusable Filter class for it, similar to FileFilter. (See korifey's answer for the use of guava.) Other than that, no, there isn't any existing functionality to do it. Additionally, any existing functionality would have to do exactly what you're doing anyway, as the List types don't have any way of knowing where the different classes of objects are in the list. (It would have to iterate over them as well to find them.)

If you require a high-performance solution around this, you could consider storing separate lists for your separate instances - either in replacement of or in addition to your current list. You could even wrap this up in a composite class that would offer both functionalities (all instances and instances by class) through a common API.

like image 68
ziesemer Avatar answered Oct 11 '22 21:10

ziesemer


You can use guava

Like this:

for (B b: Iterables.filter(a, B.class)) {
 System.out.println (b.hi);
}
like image 41
korifey Avatar answered Oct 11 '22 21:10

korifey