当Iterator不支持remove()时如何动态修剪Java List?

时间:2012-11-21 21:23:32

标签: java list iterator

我有以下代码:

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()行抛出。似乎某些Java Iterators不支持remove方法,并会抛出此异常。

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

所以我问:我可以做什么来遍历我的widgets数组并动态修剪名为“ Melvin ”的数组?

4 个答案:

答案 0 :(得分:3)

如果你负担得起,只需制作一份可变的清单副本。取代

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

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

答案 1 :(得分: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);
}

答案 2 :(得分:1)

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

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

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

答案 3 :(得分: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());
    }
});