使用由自身调用的removeAll()的潜在错误

iso*_*man 9 java collections

在使用Sonar进行代码审查期间,以下代码被检测为错误代码:

ArrayList<String> ops = new ArrayList<String>();
ops.add("test");
ops.removeAll(ops);
Run Code Online (Sandbox Code Playgroud)

Sonar正在抱怨集合本身所调用的removeAll.

我同意它很丑,但是这会引入错误吗?

注意:这不是我的代码,我正在审核它.

T.J*_*der 8

问题是是否ConcurrentModificationException可能导致a 或列表损坏,无限循环,或无法删除条目或类似情况.

ArrayList特别是在Oracle的JDK8中,似乎写得不会出现这些问题.

这是否意味着那个代码没问题呢?

不,这不好.

那段代码:

  • 依赖列表的实现removeAll足够聪明,可以处理一个非常奇怪的用例

  • 阅读和理解不必要地复杂,从而产生维护问题

  • 正在做不必要的工作,因此需要更长的时间来完成它所需要的工作(不是这可能是一个大问题)

您在代码审查的上下文中说过这一点.我将其标记并与作者讨论他们为何使用它,并从可靠性,维护和(非常小的)性能角度解释为什么ops.clear();ops = new ArrayList<String>();(取决于上下文)几乎肯定会是更好的选择.


Fer*_*big 6

是的,这将引入错误.默认情况下removeAll工作原理是Iterator,如果你修改集合而不使用迭代器,它会给出一个ConcurrentModificationException.如果它给出这个例外与否取决于Collection你正在使用的内部设计,并且不能依赖.

尽管当前版本没有使用iterator(),但是没有记录,Oracle可能会在不事先通知的情况下对其进行更改.

要清除集合,您可以使用.clear().