[英]How to dynamically prune Java List when Iterator does not support remove()?
I have the following code: 我有以下代码:
Widget[] widgetArray = widgetService.getAllWidgets();
List<Widget> widgets = Arrays.asList(widgetArray);
// Prune out any Widgets named "Melvin".
Iterator<Widget> iter = widgets.iterator();
while(iter.hasNext()) {
Widget w = iter.next();
if("Melvin".equals(w.getName()))
iter.remove();
}
When I run this code I get a runtime java.lang.UnsupportedOperationExceptionError
with a vague exception message of null
that gets thrown on the iter.remove()
line. 当我运行此代码时,我得到一个运行时
java.lang.UnsupportedOperationExceptionError
,它带有模糊的null
异常消息,该消息会抛出在iter.remove()
行上。 It seems that some Java Iterators
don't support the remove
method and will throw this exception. 似乎某些Java
Iterators
不支持remove
方法,并且会抛出此异常。
I can't change the widgetService.getAllWidgets()
method to return a List<Widget>
and am stuck with the Widget[]
array return value. 我无法更改
widgetService.getAllWidgets()
方法以返回List<Widget>
并且卡在Widget[]
数组返回值中。
So I ask: what can I do to loop through my widgets
array and dynamically prune out ones that are named " Melvin "? 因此,我问:我该怎么做才能遍历
widgets
数组并动态修剪掉名为“ Melvin ”的widgets
?
If you can afford it, just make a mutable copy of the list. 如果您负担得起,只需复制列表即可。 Replace
更换
List<Widget> widgets = Arrays.asList(widgetArray);
with 同
List<Widget> widgets = new ArrayList<Widget>(Arrays.asList(widgetArray));
Just defer removal until the iterator is done: 只需将删除推迟到迭代器完成为止:
Widget[] widgetArray = widgetService.getAllWidgets();
List<Widget> widgets = Arrays.asList(widgetArray);
// Prune out any Widgets named "Melvin".
List<Widget> toRemove = new ArrayList<Widget>();
Iterator<Widget> iter = widgets.iterator();
while(iter.hasNext()) {
Widget w = iter.next();
if("Melvin".equals(w.getName()))
toRemove.add(w);
}
widgets.removeAll(toRemove);
Alternatively, just build the list from eligible widgets using the inverse logic: 或者,只需使用反逻辑从符合条件的小部件中构建列表:
List<Widget> widgets = new ArrayList<Widget>();
// Add all Widgets not named "Melvin"
for (Widget w : widgetService.getAllWidgets()) {
if(!"Melvin".equals(w.getName()))
widgets.add(w);
}
The asList()
list is still backed by the array. 数组仍支持
asList()
列表。
You may want to loop through each element of the array and add it to a brand new list. 您可能需要遍历数组的每个元素,并将其添加到全新列表中。 This would take two loops.
这将需要两个循环。
Or better yet, compare the string value and then add to the list. 或者更好的方法是,比较字符串值,然后将其添加到列表中。 This way, you have one loop and a brand new list.
这样,您就有一个循环和一个全新的列表。
With guava you can get rid of all that code and let a fast, well tested library take care of it for you. 使用番石榴,您可以摆脱所有这些代码,并让一个快速,经过良好测试的库为您处理它。
Collection<Widget> noMelvins = Collections2.filter( Arrays.asList(widgetArray), new Predicate<Widget>() {
@Override public boolean apply( final Widget arg) {
return !"Melvin".equals(arg.getName());
}
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.