为什么在我尝试以下代码时会抛出Unsupported异常?

huangapple go评论75阅读模式
英文:

Why Does Unsupported exception is thrown when i am trying below code?

问题

上面的代码在 list.remove(student) 行引发了不支持的操作异常。这是因为方法参数中的 List<? extends Student> list 导致的吗?

英文:
public void process(List&lt;? extends Student&gt; list) {
  List&lt;Student&gt; list = (List&lt;Student&gt;) items;
  for (Student student : list) {
    if (student.getAge &gt; 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 -&gt; s.getAge() &gt; 60);

If you need to do something with the item you're removing, use an Iterator:

Iterator&lt;? extends Student&gt; it = list.iterator();
while (it.hasNext()) {
  Student s = it.next();
  if (s.getAge() &gt; 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&lt;Student&gt; removedStudent = list.stream()
                                   .filter(s -&gt; s.getAge() &gt; 60)
                                   .collect(Collectors.toList());

Then remove from the list

list.removeIf(s -&gt; s.getAge() &gt; 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()

huangapple
  • 本文由 发表于 2020年8月4日 18:04:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/63244567.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定