for(CityDataVO cityItem: citys){
boolean flag =false;
for(ProvinceDataVO proItem : list){
xxxxxx
flag = true;
break;
}
if(!flag){
ProvinceDataVO province = new ProvinceDataVO();
province.setProvinceId(cityItem.getProvinceId());
province.setProvinceName(cityItem.getProvinceName());
province.setReportNum(cityItem.getCount());
List<CityDataVO> vo = new ArrayList<>();
vo.add(cityItem);
province.setCityData(vo);
list.add(province);
}
}
比如上面的代码,如果我没有进入第二层的for循环里,我就会对list进行一个add的操作。这里应该是没有问题的,因为我在第一个for循环体里操作的是第二个for循环的size()。我记得有一个情景是for(){...}我直接在...操作了for的size(),这样好像是不行的,当初好像有一个什么办法的,我暂时想不到了,哪位大神帮我回忆回忆呵??
大家讲道理2017-06-28 09:25:52
在for each,也就是你的代码里 for(a : as)的循环中,不能对被循环集合进行增加或删除操作,否则会报ConcurrentModificationException.
在这段代码里是没有问题的。因为你改变list的操作都是在内层循环之外做的。
看你的需求其实就是按省统计各市的数据。有条件使用Java 8的话,可以看看Stream的GroupBy方法。可以大大简化代码。
一些不相太干的问题,set方法设置一个list的方式是不太合适的。
如果是有业务逻辑的对象,应该对内部结构进行包装后以业务领域的概念提供接口,而不应该直接暴露内部的集合。
即便是数据传递对象,也不应该提供集合属性的set方法。一般而言,私有集合变量的生命周期应该由它的父对象管理。外界通过外面包装对象的add或remove方法操作私有的集合。如果需要提供集合方式的get方法。需要考虑是否要进行copy或者使之不可变。
伊谢尔伦2017-06-28 09:25:52
希望直接跳出两层循环,无非是两种办法:
用break label
的语法(这个我从没用过,可以Google一下);
就是你用的办法,设个标志位。
另外,city
的复数是cities
而不是citys
。
世界只因有你2017-06-28 09:25:52
这写得啰嗦了。我的话先这样写:
for (CityDataVO cityItem: citys){
if (validateCityItem(cityItem, list)) {
continue;
}
List<CityDataVO> vo = new ArrayList<>();
vo.add(cityItem);
ProvinceDataVO province = new ProvinceDataVO();
province.setProvinceId(cityItem.getProvinceId());
province.setProvinceName(cityItem.getProvinceName());
province.setReportNum(cityItem.getCount());
province.setCityData(vo);
list.add(province);
}
...
private boolean validateCityItem(CityDataVO cityItem, List<ProvinceDataVO> list) {
for(ProvinceDataVO proItem : list){
if (...) {
return true;
}
}
return false;
}
你的原代码有几个需要优化的地方:
尽量避免双重循环,内循环一般都应该提取出来;
对同一个变量的操作,代码行尽可能集中在一起,这样阅读起来更自然;
变量命名应当表现其业务含义和主要类型,比如 List 对象尽量都用 xxxList 方式命名。这我懒得给你改了。