迭代在第一次迭代后退出

时间:2016-01-08 19:27:04

标签: java collections

我正在尝试比较两个不同的List并删除重复项。但是,这两个列表有两种不同的对象类型,只有公共属性是app name。

这是代码,

public List<TvAppsType> getAvailableAppsTypesByCompanyIdSecond(int comapnyId) {
    // put apps to the model that belong to the given company id
    TVAppService tvAppService = new TVAppService();
    List<ThreatviewApp> apps = new CopyOnWriteArrayList<ThreatviewApp>();
    apps = tvAppService.getAllAppsforCompanyId(comapnyId);

    // get list of app types
    TvAppTypeService types = new TvAppTypeService();
    List<TvAppsType> apptypes = new CopyOnWriteArrayList<TvAppsType>();
    apptypes = types.getAppTypes();
    // add the items to collection for removing
    for(TvAppsType app : apptypes){
        System.out.println("-----------------------");
        System.out.println("app : " + app.getAppType_name());
    }

    Iterator<TvAppsType> itertypes = apptypes.iterator();
    Iterator<ThreatviewApp> it = apps.iterator();
    while (itertypes.hasNext()) {
        TvAppsType apptype = itertypes.next();
        while (it.hasNext()) {
            ThreatviewApp tvapp = it.next();
            if (tvapp.getApp_name().trim().equals(apptype.getAppType_name().trim())) {
                itertypes.remove();
            }
        }
    }

    for(TvAppsType app : apptypes){
        System.out.println("-----------------------");
        System.out.println("app : " + app.getAppType_name());
    }

    return apptypes;
}

问题是这只适用于第一次迭代,我怀疑在修改List之后,迭代行为是未指定的。

  

void remove()从底层集合中移除最后一个元素   由此迭代器返回(可选操作)。这种方法可以   每次调用next()时只调用一次。迭代器的行为是   如果底层集合被修改,则未指定   迭代正在以任何方式进行,而不是通过调用此方法。

在我尝试修改列表运行时时,我使用了CopyOnWriteArrayList 基本上,我遵循了这篇文章article

为什么迭代在第一个之后停止?如何解决此问题并删除所有重复项?

2 个答案:

答案 0 :(得分:1)

除了@Eran的回答,你还有另外一个问题。删除 while (it.hasNext()) { ThreatviewApp tvapp = it.next(); if (tvapp.getApp_name().trim().equals(apptype.getAppType_name().trim())) { itertypes.remove(); break; } } (在内部while循环中)后,永远不要再尝试删除同一个对象。此外,尽快退出内循环将加速您的算法。

因此,内部循环应如下所示:

@echo off
set /p hostname=PC hostname?
echo.
FOR /F "skip=1 tokens=*" %%A in ('wmic /node:%hostname% OS get caption') DO echo %%A
echo.
pause

答案 1 :(得分:0)

如果希望在apps列表上多次迭代,则必须重置内循环的迭代器。否则,内部while循环将仅在apps列表上迭代一次,之后it.hasNext()将为false。

Iterator<TvAppsType> itertypes = apptypes.iterator();
while (itertypes.hasNext()) {
    TvAppsType apptype = itertypes.next();
    Iterator<ThreatviewApp> it = apps.iterator(); // the inner iterator must be
                                                  // initialized in each iteration
                                                  // of the outer loop
    while (it.hasNext()) {
        ...