I am trying to use the Iterables class to filter an ArrayList, but when I try to cast the result back to the original type I get a ClassCastException at runtime.
// domains is an ArrayList<Domain> which is defined earlier in the class
Iterable<Domain> temp = Iterables.filter(domains, new Predicate<Domain>() {
public boolean apply(Domain input) {
if (input.getName().toLowerCase().contains(filter.toString().toLowerCase())) {
return true ;
} else {
return false;
}
}
}) ;
ArrayList<Domain> filteredDomains = (ArrayList<Domain>) temp ; // Error occurs here
To be complete, I am trying to use this in an开发者_C百科 Android application with a target of 1.6.
temp
is not an ArrayList<Domain>
. It is an Iterable<Domain>
.
If you absolutely need an ArrayList<Domain>
(or a List<Domain>
in general), then you need to take a slightly different approach.
First, use Collections2.filter()
instead of Iterables.filter()
: to produce temp
and then create a new ArrayList
from the resulting Collection
:
Collection<Domain> temp = Collections2.filter(domains, myPredicate) ;
List<Domain> filteredDomains = new ArrayList<Domain>(temp);
But you should really think if you need a List
or ArrayList
and if a Collection
is not enough for what you want. If an Iterable
is sufficient (for example if you only iterate over the content), then you can even keep using Iterables.filter()
.
The real return type is an anonymous class that extends IterableWithToString
- and we cannot cast that type to ArrayList
.
Here's the implementation on grepcode.
Temp is an Iterable not an ArrayList. Further more an ArrayList is an Iterable but not vice versa. What if you had
Iterable<?> iterable = new HashSet<?>();
You can see why a class cast exception would happen here.
To create an ArrayList from the Iterable you would have to iterate over the iterable itself and add to a new ArrayList
List<Domain> filteredDomains = new ArrayList<Domain>();
for(Iterator<Domain> i = temp.iterator(); i.hasNext();){
filteredDomains.add(i.next());
}
精彩评论