public List<CabinetStatisticBO> findCabinetStatistic(
CabinetStatisticSpec spec) {
List list = baseDAO.query(spec);
List<CabinetStatisticBO> statList = new ArrayList<CabinetStatisticBO>(); if (list != null && !list.isEmpty()) {
for (Object obj : list) {
CabinetStatisticBO statBO = new CabinetStatisticBO();
// 机房名称
String compLocaName = "";
// 已满机柜数
Integer fullCabinet = 0;
// 未满机柜数
Integer nofullCabinet = 0;
// 未使用机柜数
Integer unusedCabinet = 0;
// 总计
Integer totalCabinet = 0;
NetworkCabinets cabinet = (NetworkCabinets) obj;
// 机房名称
compLocaName = cabinet.getComputerLocation().getName();
// 可使用高度
Integer allowHeight = cabinet.getAllowHeight();
// 已使用高度
Integer useHigh = cabinet.getUseHigh();
// 已满机柜数
if (useHigh != null && useHigh > 0
&& allowHeight - useHigh <= 0) {
fullCabinet += 1;
}
// 未满机柜数
if (useHigh != null && useHigh > 0 && allowHeight - useHigh > 0) {
nofullCabinet += 1;
}
// 未使用机柜数
if (useHigh == null || useHigh == 0) {
unusedCabinet += 1;
}
totalCabinet = fullCabinet + nofullCabinet + unusedCabinet; if (statList == null || statList.isEmpty()) {
statBO.setCompLocaName(compLocaName);
statBO.setFullCabinet(fullCabinet);
statBO.setNofullCabinet(nofullCabinet);
statBO.setUnusedCabinet(unusedCabinet);
statBO.setTotalCabinet(totalCabinet);
statList.add(statBO);
} else {
for(Iterator iter = statList.iterator();iter.hasNext();) {
CabinetStatisticBO cs = (CabinetStatisticBO) iter
.next();
if (cs.getCompLocaName().equals(compLocaName)) {
cs
.setFullCabinet(fullCabinet
+ cs.getFullCabinet());
cs.setNofullCabinet(nofullCabinet
+ cs.getNofullCabinet());
cs.setUnusedCabinet(unusedCabinet
+ cs.getUnusedCabinet());
cs.setTotalCabinet(totalCabinet
+ cs.getTotalCabinet());
} else { statBO.setCompLocaName(compLocaName);
statBO.setFullCabinet(fullCabinet);
statBO.setNofullCabinet(nofullCabinet);
statBO.setUnusedCabinet(unusedCabinet);
statBO.setTotalCabinet(totalCabinet);
statList.add(statBO); //在这里会发生异常
}
}
} }
} return statList;
}要求在执行statList.add(statBO); 后继续循环遍历for(Iterator iter = statList.iterator();iter.hasNext();)
寻求网上解决办法没找到,一般就是讨论列表中元素的删除问题,即remove()
而add()不知道怎么解决呢??
也可以判断结束的条件(虽然往里面添加东西,但总有结束的条件),结束了就不在遍历了,不结束的话您老继续
始终感觉这样子的实现不太好,建议楼主更换实现的思路
要做的是统计机房里面机柜的使用情况:机柜总计、未满机柜数、已满机柜数、未使用机柜数
这里我查询的是机柜实体类,也就是已机柜为主,机房没有机柜的不统计
如果不对列表进行处理,直接把机房名称和那些统计数设置一次,就添加到列表中,返回回去的列表是一个一个的列出每个机柜,同一个机房的机柜的统计数字根本没进行相加操纵数据库的SQL语句贴出来大家就明白了:机柜表:network_cabinets(ID int,COMP_LOCA_ID int,HEIGHT int,USE_HEIGHT int)
机房表:computer_location(ID int,NAME varchar)
其中,COMP_LOCA_ID是机房表的ID,HEIGHT是机柜的高度,USE_HEIGHT是已经使用的高度
现在要统计每个机房的机柜总数、未使用机柜总数(即已使用高度为空或等于0)、
未满机柜数(即已使用高度不为空并且大于0,并且高度-已使用高度>0)
已满机柜数(即已使用高度不为空并且大于0,并且高度=已使用高度) select l.NAME,
count(*) as 机柜总计,
sum(if(r.USE_HEIGHT is null or r.USE_HEIGHT=0,1,0)) as 未使用机柜数,
sum(if(r.USE_HEIGHT>0 and r.USE_HEIGHT<r.HEIGHT,1,0)) as 未满机柜数,
sum(if(r.USE_HEIGHT>=r.HEIGHT,1,0)) as 已满机柜数
from network_cabinets r,computer_location l
where r.COMP_LOCA_ID=l.ID
group by l.NAME
CabinetStatisticBO cs = (CabinetStatisticBO) iter
.next();
if (cs.getCompLocaName().equals(compLocaName)) {
cs
.setFullCabinet(fullCabinet
+ cs.getFullCabinet());
cs.setNofullCabinet(nofullCabinet
+ cs.getNofullCabinet());
cs.setUnusedCabinet(unusedCabinet
+ cs.getUnusedCabinet());
cs.setTotalCabinet(totalCabinet
+ cs.getTotalCabinet());
} else { statBO.setCompLocaName(compLocaName);
statBO.setFullCabinet(fullCabinet);
statBO.setNofullCabinet(nofullCabinet);
statBO.setUnusedCabinet(unusedCabinet);
statBO.setTotalCabinet(totalCabinet);
statList.add(statBO); //在这里会发生异常
}
}
这里写的有问题,不是逻辑或者其他问题,这么做肯定会有问题的,Iterator iter = statList.iterator();iter.hasNext();这么将list转换成iterator再CabinetStatisticBO cs = (CabinetStatisticBO) iter
.next();进而想改变cs的属性,这样做不是可能会出现问题,是一定会出现问题,相信lz查查ConcurrentModificationException产生的原因就知道了或者查查Iterator的api,建议lz直接用list的get方法来取得相应对象,进而改变其属性。
但是到else那add元素绝对有问题,因为list在遍历过程中,改变了list元素数量,就会抛那个异常
还有,用list循环还是Interator来循环都是一样的
你可以试试用Interator来操纵list的情况
而且,我list定义的时候就给定是CabinetStatisticBO泛型,所以转换不会有问题
List<CabinetStatisticBO> statList = new ArrayList<CabinetStatisticBO>();
if (list != null && !list.isEmpty()) {
for (Object obj : list) {
CabinetStatisticBO statBO = new CabinetStatisticBO();
}
}如果在上面这个循环里,把值就直接设置到statBO ,再将statBO add到statList ,这样statList列表的元素为多个CabinetStatisticBO,这些BO里面有一些compLocaName相同,我想将compLocaName的BO的那四个统计数字分别相加,得到的相加后的四个统计数字再设置给其中一个BO,compLocaName机房名称不变,其它的BO remove掉
也就是对statList 用一个两层循环,像排序法那样,挨个取出机房名称,相同的话将统计数字相加,设置到其中一个对象中,另一个对象则删掉;这样一直循环下去,到最后得到的就是根据不同机房,得到机柜的统计数字
列表在遍历时要移除只能采用Iterator的remove方法
public class Score { private String name;
private Integer chinese;
private Integer math;
public static void main(String[] args) {
List<Score> scores = new ArrayList<Score>();
Score score1 = new Score();
score1.name="张三";
score1.chinese = 89;
score1.math = 90;
Score score2 = new Score();
score2.name="张三";
score2.chinese = 78;
score2.math = 83;
Score score3 = new Score();
score3.name="李四";
score3.chinese = 67;
score3.math = 50;
Score score4 = new Score();
score4.name="王五";
score4.chinese = 88;
score4.math = 99;
Score score5 = new Score();
score5.name="李四";
score5.chinese = 80;
score5.math = 86;
Score score6 = new Score();
score6.name="王五";
score6.chinese = 90;
score6.math = 96;
Score score7 = new Score();
score7.name="张三";
score7.chinese = 76;
score7.math = 90;
Score score8 = new Score();
score8.name="李四";
score8.chinese = 88;
score8.math = 83;
scores.add(score1);
scores.add(score2);
scores.add(score3);
scores.add(score4);
scores.add(score5);
scores.add(score6);
scores.add(score7);
scores.add(score8); for(int i=0;i<scores.size();i++){
for(int j=i+1;j<scores.size();j++){
Score s1 = scores.get(i);
Score s2 = scores.get(j);
if(s1.name.equals(s2.name)){
Integer chinese2 = s2.chinese;
Integer math2 = s2.math;
s1.chinese=s1.chinese+chinese2;
s1.math=s1.math+math2;
scores.remove(s2);
}
}
}
for(int i=0;i<scores.size();i++){
Score s = scores.get(i);
System.out.println(s.name+":语文="+s.chinese+" 数学="+s.math);
}
}}
运行结果:
张三:语文=243 数学=263
李四:语文=235 数学=219
王五:语文=178 数学=195我作了下测试,能统计名字相同的对象的其它属性,去掉多余的对象,运行正常,不知道这样两层循环会不会有别的问题?有一点,就是性能会很差
// 贴出统计类CabinetStatisticBO public class CabinetStatisticBO {
/** 机房名称 */
private String compLocaName;
/** 已满机柜数 */
private Integer fullCabinet;
/** 未满机柜数 */
private Integer nofullCabinet;
/** 未使用机柜数 */
private Integer unusedCabinet;
/** 机柜总数 */
private Integer totalCabinet;
public Integer getFullCabinet() {
return fullCabinet;
} public void setFullCabinet(Integer fullCabinet) {
this.fullCabinet = fullCabinet;
} public Integer getNofullCabinet() {
return nofullCabinet;
} public void setNofullCabinet(Integer nofullCabinet) {
this.nofullCabinet = nofullCabinet;
} public Integer getTotalCabinet() {
return totalCabinet;
} public void setTotalCabinet(Integer totalCabinet) {
this.totalCabinet = totalCabinet;
} public Integer getUnusedCabinet() {
return unusedCabinet;
} public void setUnusedCabinet(Integer unusedCabinet) {
this.unusedCabinet = unusedCabinet;
}
public String getCompLocaName() {
return compLocaName;
} public void setCompLocaName(String compLocaName) {
this.compLocaName = compLocaName;
}
因为我要判断列表中元素机房名称是否和外面那个遍历过程中的机房名称相同,如果相同,直接改变列表中统计数字的值,将列表中统计的值取出和当前的外层遍历的统计值相加,
不就是机房相同的机柜使用情况得到了统计嘛?等startList 添加完后,列表里是所有机柜,再如何进行统计?用两层循环?机房名字相同的,统计数字进行相加,设置到其中一个对象的属性中?另外对象删除掉?
我也这么想过,但是达不到效果看看我回复在上面的测试程序,那样是行不通的,那段程序运行结果貌似正确,改变list里面的元素个数,就不对了
刚开始就是用的list的get方式做的
看来你对Iterator不太了解,它本来就是用来迭代集合的,迭代的哪个List,next()当然就是那个List里面的元素,哪里是强制转换??
你去试试用Iterator来迭代list进行输出吧
java基础问题,呵呵
List list = new ArrayList(){{
add("1");
add("2");
add("3");
}};
for(ListIterator iter = list.listIterator(0);iter.hasNext();iter.next()) {
if (new Random().nextBoolean()) {
iter.add("4");
}
}
System.out.println(list);
2.把抛出异常的那行代码,换成iter.add(statBO)。原因是,Iterator中有List中某些元素的缓存,所以,当List中元素个数发生变化的时候,造成Iterator的不同步。
他们把元素的个数的改变以及元素本身内容的改变称为状态的改变。
因为缓存的存在,使得List的状态改变后,无法同步给Iterator。
所以会抛出那个什么异常。
不就行了,也不要考虑同步什么的问题了,在循环里面添加元素也不会有问题。
不要用for(Object o : list)这种循环,它实际上也是用Iterator实现的。
import java.util.HashMap;
import java.util.List;
import java.util.Map;public class Score { private String name;
private Integer chinese;
private Integer math;
public static void main(String[] args) {
List<Score> scores = new ArrayList<Score>();
Score score1 = new Score();
score1.name="张三";
score1.chinese = 89;
score1.math = 90;
Score score2 = new Score();
score2.name="张三";
score2.chinese = 78;
score2.math = 83;
Score score3 = new Score();
score3.name="李四";
score3.chinese = 67;
score3.math = 50;
Score score4 = new Score();
score4.name="王五";
score4.chinese = 88;
score4.math = 99;
Score score5 = new Score();
score5.name="李四";
score5.chinese = 80;
score5.math = 86;
Score score6 = new Score();
score6.name="王五";
score6.chinese = 90;
score6.math = 96;
Score score7 = new Score();
score7.name="张三";
score7.chinese = 76;
score7.math = 90;
Score score8 = new Score();
score8.name="李四";
score8.chinese = 88;
score8.math = 83;
scores.add(score1);
scores.add(score2);
scores.add(score3);
scores.add(score4);
scores.add(score5);
scores.add(score6);
scores.add(score7);
scores.add(score8);
Map<String,Score> scoreMap = new HashMap<String,Score>();
for(Score score:scores){
Score temp =scoreMap.get(score.name);
if(temp==null)
scoreMap.put(score.name, score);
else{
temp.chinese+=score.chinese;
temp.math+=score.math;
}
}
List<Score> result = new ArrayList<Score>(scoreMap.values());
System.out.println(result);
}
public String toString(){
return name+":语文="+this.chinese+" 数学="+this.math;
}}