当我尝试在此列表中使用迭代器时,为什么会抛出此异常?

时间:2015-01-26 09:23:05

标签: java list iterator java-collections-api

我有这种类型的集合:

List<com.liferay.portal.model.Role> ruoli
ruoli = currentUser.getRoles(); 

包含3个元素(我使用调试器看到它​​),每个 Role 对象都有一个 name 字段,而previos列表中的3个对象具有以下名称: 管理员高级用户用户

所以我试图使用迭代器来迭代这个列表并打印包含在 ruoli 列表中的这3个对象的name字段的值,所以我这样做:

Iterator<Role> iteratorUserRoles = ruoli.iterator();

while (iteratorUserRoles.hasNext()) {
    System.out.println(iteratorUserRoles.next().getName());
    iteratorUserRoles.next();
}

问题在于它没有显示

但是在堆栈跟踪中我得到了:

**Administrator**
**Power User**
**User**

正如我所料,但我收到了这条消息:

**Administrator**
**User**

然后抛出此异常:

2015-01-26 10:20:13,071 [[ACTIVE] ExecuteThread:&#39; 1&#39; for queue:&#39; weblogic.kernel.Default(self-tuning)&#39;] ERROR commons.CommonsLogger.error(38) - 无法执行操作 java.util.NoSuchElementException

尝试执行此操作时似乎抛出了异常:

iteratorUserRoles.next();

为什么呢?可能是什么问题呢?我在做什么?如何解决此问题并正确地将所有对象迭代到我的列表中?

TNX

3 个答案:

答案 0 :(得分:5)

你在每次迭代中推进迭代器两次。

while (iteratorUserRoles.hasNext()) {
    System.out.println(iteratorUserRoles.next().getName());
    //iteratorUserRoles.next(); remove this
}

如果迭代器有一个剩余元素并且你两次调用iteratorUserRoles.next(),那么你将获得例外。

答案 1 :(得分:1)

Iterator#next()不是吸气剂。它使指针前进并将元素返回到新位置。

如果需要触摸两次,请将返回的值分配给变量:

Iterator<Role> iteratorUserRoles = ruoli.iterator();

while (iteratorUserRoles.hasNext()) {
    Role role = iteratorUserRoles.next();
    System.out.println(role.getName());
    // do something else with role
}

答案 2 :(得分:1)

你在while循环中调用iterator.next()两次。这就是你获得异常的原因(为什么你错过了第二个元素)

但是我建议你不要以这种方式访问​​迭代器。像这样循环使用它的机制。

for (com.liferay.portal.model.Role role : ruoli){
    System.out.println(role.getName());
}