我试图将我的数据库中具有相同名称的所有位置收集到一个列表中,为了做到这一点我使用它:
public static List<Location> searchRepe(List<Location>ls){
List<Location>res=new ArrayList<Location>();
for(Location l:ls){
ls.remove(l);
if(ls.stream().anyMatch(x>x.getProvinceName().equals(l.getProvinceName()))){
res.add(l);}
ls.add(l);
}
return res;
}
错误:线程中的异常&#34; main&#34; java.util.ConcurrentModificationException
我首先删除列表的位置,然后检查是否存在具有相同名称的其他位置。在检查了该位置的名称是否在列表中之后,我将其添加到我的res列表中。在任何情况下,我将始终保持原始列表相同,因为在检查后我读取列表中的元素。我知道错误是由于我删除并添加每次迭代但是如果在每次迭代中我删除然后添加相同的元素,则列表的大小将始终相同。
有人可以告诉我更好的方法吗?如果可以使用java8
答案 0 :(得分:0)
foreach
语句使用Iterator
来检索项目,Iterator
无法直接删除项目,否则该方法将抛出ConcurrentModificationException
。因此,您可以通过以下方法从列表中删除项目:
for (int index = 0; index < list.size(); index++) {
if(condition){
list.remove(index);
index--;
}
}
在您的问题中,您可以在Multimap
库中使用Guava
这是一个新的集合类型,如下所示:
public static List<Location> searchRepe(List<Location>ls){
Multimap<String,Location> locationMap = HashMultimap.create();
for (Location l : ls) {
locationMap.put(l.getProvinceName(),l);
}
List<Location> result=new ArrayList<>();
for (Map.Entry<String, Collection<Location>> entry : locationMap.asMap().entrySet()) {
Collection<Location> value = entry.getValue();
if(value.size()>1){
Location next = value.iterator().next();
result.add(next);
}
}
return result;
}
请注意此行locationMap.put(l.getProvinceName(),l)
,put
方法的结果取决于equals
类中的Location
方法。
答案 1 :(得分:0)
如果你绝对想要使用stream和java8,我相信这是正确的解决方案。
只需根据ProvinceName
多个
public static List<Location> searchRepe(List<Location> ls) {
return ls.stream()
.filter(
location -> ls.stream()
.map(Location::getProvinceName)
.filter(n -> Objects.equals(n, location.getProvinceName()))
.count() > 1L
)
.collect(Collectors.toList());
}
或使用分组
public static List<Location> searchRepe(List<Location> ls) {
return ls.stream()
.collect(Collectors.groupingBy(Location::getProvinceName))
.entrySet()
.stream()
.map(Map.Entry::getValue)
.filter(entry -> entry.size() > 1)
.map(entry -> entry.get(1))
.collect(toList());
}