iterator.remove();报null错误
时间: 2023-05-03 12:05:44 浏览: 217
iterator.remove() 报 null 错误一般是因为没有先使用 iterator.next() 方法来检查下一个元素是否存在。
在使用 Iterator 迭代器进行遍历时,需要先使用 iterator.next() 方法来判断下一个元素是否存在并获取下一个元素,然后再使用 iterator.remove() 方法来移除当前元素。如果没有先通过 iterator.next() 方法来获取下一个元素,就直接使用 iterator.remove() 方法,就会报 null 错误。
另外,还有可能是在使用迭代器时改变了集合的结构,例如增删元素等操作,会导致迭代器遍历出错,也会报 null 错误。
因此,解决该问题的方法是先使用 iterator.next() 方法来判断下一个元素是否存在并获取下一个元素,确保元素存在后再使用 iterator.remove() 方法来移除当前元素。如果需要对集合进行增删元素等操作,建议在遍历结束后再进行操作,或者使用 ListIterator 来遍历和修改集合。
相关问题
/*根据sourceTableId查询数据*/ List<DlLineage> dlLineageList = getLineageListBySourceTableIds(null, null, Arrays.asList(451L)); /*源端数据处理*/ List<DlLineage> dlLineageListCopySource = new ArrayList<>(); Iterator<DlLineage> iterator = dlLineageList.iterator(); while (iterator.hasNext()) { /*获取源端的数据*/ if (iterator.next().getSourceLayer().equals(LayerTypeEnum.SOURCEEND.getCode())) { dlLineageListCopySource.add(iterator.next()); /*删除源端列表数据*/ dlLineageList.remove(iterator.next()); } }产生java.util.ConcurrentModificationException: null异常, if (iterator.next().getSourceLayer().equals(LayerTypeEnum.SOURCEEND.getCode()))出现问题并给出解决办法
产生`java.util.ConcurrentModificationException: null`异常是因为在使用迭代器遍历集合时,修改了集合的结构(删除了元素),导致迭代器失效。
问题出现在以下代码行:
```java
dlLineageList.remove(iterator.next());
```
解决办法是使用迭代器的 `remove()` 方法来删除元素,而不是直接使用集合的 `remove()` 方法。
以下是修正后的代码示例:
```java
Iterator<DlLineage> iterator = dlLineageList.iterator();
while (iterator.hasNext()) {
DlLineage dlLineage = iterator.next();
if (dlLineage.getSourceLayer().equals(LayerTypeEnum.SOURCEEND.getCode())) {
dlLineageListCopySource.add(dlLineage);
iterator.remove(); // 使用迭代器的 remove() 方法删除元素
}
}
```
通过使用迭代器的 `remove()` 方法来删除元素,可以避免 `ConcurrentModificationException` 异常的发生。
for (DatabaseType d : dataTypes) { DatabaseContextHolder.setDatabaseType(d); List<String> bankPaidOutRefNbrs = unionLoanMapper.getCustPaidOutRefNbrsUnionLoan(); if(!CollectionUtils.isEmpty(bankPaidOutRefNbrs)){ DatabaseContextHolder.setDatabaseType(d); List<PaidOutRemainBalVo> unionBankBals = unionLoanMapper.getUnionBalByRefNbrs(bankPaidOutRefNbrs); List<String> refNbrs = unionBankBals.stream().map(p -> p.getRefNbr()).collect(Collectors.toList()); DatabaseContextHolder.setDatabaseType(d); List<String> waiveRefNbrs = new ArrayList<>(); if (!CollectionUtils.isEmpty(refNbrs)){ waiveRefNbrs = unionLoanMapper.getUnionWaiveRefNbr(refNbrs); } Iterator<PaidOutRemainBalVo> iterator = unionBankBals.iterator(); while (iterator.hasNext()) { PaidOutRemainBalVo vo = iterator.next(); //排除豁免未入账 if (!CollectionUtils.isEmpty(waiveRefNbrs)) { if (waiveRefNbrs.contains(vo.getRefNbr())) { iterator.remove(); continue; } } //去除三峡本金为负数的告警 if (vo.getCoopId() != null && vo.getCoopId().contains("SXBANK") && vo.getPrincipalBal().compareTo(BigDecimal.ZERO) < 0) { iterator.remove(); } } if (!CollectionUtils.isEmpty(unionBankBals)){ unionBalsAll.addAll(unionBankBals); } } } 用多线程实现该循环
可以使用Python内置的`concurrent.futures`模块中的`ThreadPoolExecutor`来实现多线程循环。具体代码如下:
```python
from concurrent.futures import ThreadPoolExecutor
from functools import partial
def process_data(d, data):
DatabaseContextHolder.setDatabaseType(d)
bankPaidOutRefNbrs = unionLoanMapper.getCustPaidOutRefNbrsUnionLoan()
if not bankPaidOutRefNbrs:
return []
DatabaseContextHolder.setDatabaseType(d)
unionBankBals = unionLoanMapper.getUnionBalByRefNbrs(bankPaidOutRefNbrs)
refNbrs = [p.getRefNbr() for p in unionBankBals]
DatabaseContextHolder.setDatabaseType(d)
waiveRefNbrs = unionLoanMapper.getUnionWaiveRefNbr(refNbrs) if refNbrs else []
result = []
for vo in unionBankBals:
if waiveRefNbrs and vo.getRefNbr() in waiveRefNbrs:
continue
if vo.getCoopId() and "SXBANK" in vo.getCoopId() and vo.getPrincipalBal() < 0:
continue
result.append(vo)
return result
dataTypes = [...]
with ThreadPoolExecutor(max_workers=2) as executor:
func = partial(process_data, data=dataTypes)
results = executor.map(func, dataTypes)
unionBalsAll = []
for result in results:
if result:
unionBalsAll.extend(result)
```
以上代码中,我们将原来的循环拆分成了一个`process_data`函数,并使用`partial`函数将`dataTypes`作为参数传递给该函数。接着,创建一个`ThreadPoolExecutor`实例,设置最大工作线程数为2。使用`map`方法将`process_data`函数提交给线程池,并传入`dataTypes`参数,得到一个生成器对象`results`。最后,遍历`results`并将结果存入`unionBalsAll`中。这样就实现了多线程循环。
阅读全文