0

我有以下代码:

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();
}

当我运行此代码时,我得到一个运行时java.lang.UnsupportedOperationExceptionError,其中包含一条模糊的异常消息,null该消息被抛出iter.remove()。好像有些JavaIterators不支持这个remove方法,会抛出这个异常。

我无法更改widgetService.getAllWidgets()返回 a 的方法,并且被数组返回值List<Widget>卡住了。Widget[]

所以我问:我能做些什么来循环遍历我的widgets数组并动态删除那些名为“ Melvin ”的数组?

4

4 回答 4

3

如果您负担得起,只需制作列表的可变副本。代替

List<Widget> widgets = Arrays.asList(widgetArray);

List<Widget> widgets = new ArrayList<Widget>(Arrays.asList(widgetArray));
于 2012-11-21T21:32:45.207 回答
1

只需推迟删除,直到迭代器完成:

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);

或者,只需使用逆逻辑从符合条件的小部件构建列表:

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);
}
于 2012-11-21T21:28:00.487 回答
1

asList()列表仍然由数组支持。

您可能希望遍历数组的每个元素并将其添加到一个全新的列表中。这需要两个循环。

或者更好的是,比较字符串值,然后添加到列表中。这样,您就有了一个循环和一个全新的列表。

于 2012-11-21T21:32:14.197 回答
0

使用guava,您可以摆脱所有这些代码,让一个快速、经过良好测试的库为您处理它。

Collection<Widget> noMelvins = Collections2.filter( Arrays.asList(widgetArray), new Predicate<Widget>() {
    @Override public boolean apply( final Widget arg) {
        return !"Melvin".equals(arg.getName());
    }
});
于 2012-11-21T21:35:27.367 回答