英文:
Why Does Unsupported exception is thrown when i am trying below code?
问题
上面的代码在 list.remove(student)
行引发了不支持的操作异常。这是因为方法参数中的 List<? extends Student> list
导致的吗?
英文:
public void process(List<? extends Student> list) {
List<Student> list = (List<Student>) items;
for (Student student : list) {
if (student.getAge > 60) {
list.remove(student);
}
}
}
The above code throws unsupportedOperation Exception at list.remove(student) line. is it because of "List<? extends Student> list" in method parameters ?
答案1
得分: 3
是因为方法参数中的 "List<? extends Student> list" 吗?
不是。
这是因为您传递了一个不支持 "remove" 操作的 List
。这是一个可选操作。
除此之外,如果您没有收到 "UnsupportedOperationException",很可能会收到 "ConcurrentModificationException",因为您正在从正在迭代的 List
中删除元素。
在支持删除的 List
上,更简单、正确的方法是:
list.removeIf(s -> s.getAge() > 60);
如果您需要对要删除的项执行其他操作,请使用一个 Iterator
:
Iterator<? extends Student> it = list.iterator();
while (it.hasNext()) {
Student s = it.next();
if (s.getAge() > 60) {
it.remove();
// 执行其他操作。
}
}
然而,请注意,在循环中从列表中间(例如 ArrayList
)删除元素是低效的。
英文:
> is it because of "List<? extends Student> list" in method parameters ?
No.
It's because you're passing in a List
which doesn't support the remove
operation. It's an optional operation.
Besides this, if you didn't get the UnsupportedOperationException
, you'd likely get a ConcurrentModificationException
, because you're removing from a List
that you're iterating.
An easier, correct way (on a List
which supports removal) would be:
list.removeIf(s -> s.getAge() > 60);
If you need to do something with the item you're removing, use an Iterator
:
Iterator<? extends Student> it = list.iterator();
while (it.hasNext()) {
Student s = it.next();
if (s.getAge() > 60) {
s.remove();
// Do whatever.
}
}
However, be aware that removal from the middle of lists (e.g. ArrayList
) in a loop is inefficient.
答案2
得分: 0
AndyTurner已经解释了你的问题,我只想补充一点。
你可以使用Stream API来获取被移除的学生列表,然后记录它们。
List<Student> removedStudent = list.stream()
.filter(s -> s.getAge() > 60)
.collect(Collectors.toList());
然后从列表中移除这些学生。
list.removeIf(s -> s.getAge() > 60);
如果你重写了equals方法,你也可以使用removeAll
。
list.removeAll(removedStudent);
注意: 这里的getAge
可能是字段名,你可以只使用age
或者使用字段的getter方法,比如getAge()
。
英文:
AndyTurner already explained your problem, I just want to add.
You can use Stream API to get the removed student list and then log them
List<Student> removedStudent = list.stream()
.filter(s -> s.getAge() > 60)
.collect(Collectors.toList());
Then remove from the list
list.removeIf(s -> s.getAge() > 60);
You can use removeAll
also if you override equals method
list.removeAll(removedStudent);
Note: Here getAge
is may be field, use just age
or with a getter of field like getAge()
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论