是什么导致这个retainAll例外?

时间:2010-05-20 00:57:09

标签: java collections google-cloud-datastore

java.lang.UnsupportedOperationException: This operation is not supported on Query Results
    at org.datanucleus.store.query.AbstractQueryResult.contains(AbstractQueryResult.java:250)
    at java.util.AbstractCollection.retainAll(AbstractCollection.java:369)
    at namespace.MyServlet.doGet(MyServlet.java:101)

我正在尝试从数据存储区查询中检索一个列表,并且只保留我从列表中检索到的列表中的结果。我的两个列表都按预期填充,但我似乎无法在其中任何一个上使用retainAll。

//           List<Data> listOne = new ArrayList(query.execute(theQuery));
//           DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
//           List<Data> listTwo = new ArrayList(ds.get(keys).values());
//           listOne.retainAll(listTwo);

修改

好的,为了简化,因为这显然是多个问题,我已经停止使用低级API进行数据存储,而不是仅仅通过循环逐个拉动。

                List<MyClass> test = (List<MyClass>) query.execute();
                List<MyClass> test2 = new ArrayList<MyClass>();

                for (String key : favorites) {
                    test2.add(pm.getObjectById(MyClass.class, key));
                }

                log.info(test.toString());
                test.retainAll(test2);

以上作品。它不会抛出异常。以下确实抛出异常。唯一的区别是log.info。我很难过。

                List<MyClass> test = (List<MyClass>) query.execute();
                List<MyClass> test2 = new ArrayList<MyClass>();

                for (String key : favorites) {
                    test2.add(pm.getObjectById(MyClass.class, key));
                }

                test.retainAll(test2);

3 个答案:

答案 0 :(得分:2)

  

它不会让我在查询结果上执行新的ArrayList(),因为它返回一个对象数组。

然而,您需要将它们放在new ArrayList()中。返回的List实施显然不支持retainAll()。这就是异常告诉你的。

“普通”ArrayList支持它。如果由于泛型类型的不同而无法通过ArrayList构造函数,那么您需要在添加之前手动循环并投射每个项目。

List<Data> listTwo = new ArrayList<Data>();
for (Object object : ds.get(keys).values()) {
    listTwo.add((Data) object);
}
listOne.retainAll(listTwo);

更新:根据您的更新,这些实体显然是延迟加载/填充的。大多数ORM(DataNucleus是一个)可能确实这样做。因为我不使用DataNucleus,所以我不能详细介绍如何以“漂亮”的方式解决这个问题。但至少您现在知道问题的根本原因,并且可以通过与上述相同的方式解决。也可以在循环中填写列表test

答案 1 :(得分:1)

如果您用于“密钥列表”的集合类型不支持retainAll,则会抛出异常。你使用的是哪种类型?

答案 2 :(得分:0)

提示:您不需要迭代来填充listTwo。 只是做:

listTwo.addAll(ds.get(keys).values())