迭代中的Java迭代

时间:2015-11-16 17:29:52

标签: java loops

我需要迭代一个对象集并找到所有相同的成本类别并将它们连接在一起。我试图将while循环放入另一个while循环中。但这不起作用;我总是得到ConcurrentModificationException。为什么我还能得到这个?

如何使这项工作,以便它像两个嵌套的for循环一样工作

public Set<ExpenseItem> getConsolidatedExpenseitems(String expenseUid) {
    Expense expense = getByUid(expenseUid);

    Set<ExpenseItem> expenseItems = expense.getExpenseItems();
    Set<ExpenseItem> expenseItemsInner = expense.getExpenseItems();

    for(ExpenseItem e : expenseItems) { // ConcurrentModificationException
        Iterator<ExpenseItem> expenseItemsIteratorInner = expenseItems.iterator();

        expenseItemsIteratorInner = expenseItemsInner.iterator();
        while(expenseItemsIteratorInner.hasNext()) {
            ExpenseItem eInner = expenseItemsIteratorInner.next();
            if(e != null) {
                if(eInner.getCostCategory().equals(e.getCostCategory())) {
                    System.out.println(e.getCalculatedAmount());
                    System.out.println(eInner.getCalculatedAmount());
                    System.out.println("---");
                    expenseItemsIteratorInner.remove();
                }
            }
        }
    }

    return null;
}

3 个答案:

答案 0 :(得分:1)

麻烦的线是下面的 -

cellForRowAtIndexPath

您无法在内循环中修改 expenseItemsIteratorInner.remove(); (或任何Set对象),因为这会更改Collection的结构。例如,假设您想迭代大小为10的Set的每个元素 - 那么您的Collection循环将运行10次。但是在循环的第5次运行中,你进入另一个内循环并尝试删除/修改当前项目(在第5位) - 你的foreach循环将无法继续,因为外循环锁定了foreach。更多详情here

您可以执行的操作是将要删除的项目存储在临时Set中,然后再将其删除。有点像(未经测试,但我认为会给你这个想法) -

Set

可以找到如何移除Set<ExpenseItem> toDelete = new HashSet<>(); while(expenseItemsIteratorInner.hasNext()) { ExpenseItem eInner = expenseItemsIteratorInner.next(); if(e != null) { if(eInner.getCostCategory().equals(e.getCostCategory())) { ... toDelete.add(expenseItemsIteratorInner.next()); } } } //Code to remove items in the Set toDelete goes here. 中的项目的示例here

答案 1 :(得分:0)

当您在场景后面使用foreach语句时使用迭代器。所以你有两个迭代器,当你用其中一个迭代器删除元素时,另一个会抛出这个异常。 你可以使用常规循环   for(int i = 0; i <= set.size(); i++)

答案 2 :(得分:0)

感谢您的投入!没有它们,我可能仍然在忙着找到解决方案。我刚刚将expenseItem转移到了一个数组列表:

public ArrayList<ExpenseItemPdfDto> getConsolidatedExpenseItems(String expenseUid) {
    Expense expense = getByUid(expenseUid);
    Set<ExpenseItem> expenseItems = expense.getExpenseItems();
    Iterator<ExpenseItem> expenseItemsIterator = expenseItems.iterator();
    ArrayList<ExpenseItemPdfDto> expenseItemsList = new ArrayList<ExpenseItemPdfDto>();

    while(expenseItemsIterator.hasNext()) {
        ExpenseItem eInner = expenseItemsIterator.next();

        ExpenseItemPdfDto dto = new ExpenseItemPdfDto();
        dto.setAccountNumber(eInner.getCostCategory().getAccountNumber());
        dto.setCostCategoryName(eInner.getCostCategory().getName().getDe());
        dto.setOriginalAmount(eInner.getOriginalAmount());
        dto.setProject(eInner.getProject());
        expenseItemsList.add(dto);
    }

    double amount = 0;
    for(int i=0;i<expenseItemsList.size();i++) {
        if(expenseItemsList.get(i) != null) {
            for(int j=0;j<expenseItemsList.size();j++) {
                if(expenseItemsList.get(j) != null) {
                    if(expenseItemsList.get(i).getAccountNumber() == expenseItemsList.get(j).getAccountNumber()) {
                        if(i != j) {
                            amount = expenseItemsList.get(i).getOriginalAmount();
                            amount += expenseItemsList.get(j).getOriginalAmount();
                            expenseItemsList.get(i).setOriginalAmount(amount);
                            expenseItemsList.remove(j);
                        }
                    }
                }
            }
        }
    }

    return expenseItemsList;
}