使用来自Guava的Iterables的ClassCastException

时间:2011-07-12 14:49:58

标签: java android guava

我正在尝试使用Iterables类来过滤ArrayList,但是当我尝试将结果转换回原始类型时,我在运行时得到了ClassCastException。

// 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

要完成,我尝试在目标为1.6的Android应用程序中使用它。

3 个答案:

答案 0 :(得分:8)

temp 不是ArrayList<Domain> 。这是Iterable<Domain>

如果您绝对 需要 ArrayList<Domain>(或一般List<Domain>),那么您需要采取稍微不同的方法。< / p>

首先,使用Collections2.filter()代替Iterables.filter():生成temp,然后从生成的ArrayList中创建新的Collection

Collection<Domain> temp = Collections2.filter(domains, myPredicate) ;
List<Domain> filteredDomains = new ArrayList<Domain>(temp);

但你应该真的想到,如果你需要 ListArrayList,并且如果Collection不足以满足您的需求。如果Iterable足够(例如,如果您只对内容进行迭代),那么您甚至可以继续使用Iterables.filter()

答案 1 :(得分:0)

Temp是Iterable而不是ArrayList。此外,ArrayList是Iterable,但反之亦然。怎么样?

Iterable<?> iterable = new HashSet<?>();

你可以看到为什么会在这里发生类强制转换异常。

要从Iterable创建一个ArrayList,你必须遍历iterable本身并添加到一个新的ArrayList

List<Domain> filteredDomains = new ArrayList<Domain>();

for(Iterator<Domain> i = temp.iterator(); i.hasNext();){
  filteredDomains.add(i.next());
}

答案 2 :(得分:0)

真正的返回类型是一个扩展IterableWithToString的匿名类 - 我们无法将 类型转换为ArrayList

Here's the implementation on grepcode