最近项目中有一个页面运行非常慢,原来是数据从数据库取出简单封装成对象后直接以JSON的方式丢给 javascript 处理,对象个数比较多,甚至导致了浏览器报脚本运行太慢的警告。其中有一块代码写的不好懂,处理的逻辑大意是:从数据库返回3列比如A, B, C,其中A列有重复值,那么以A列的值进行group, 列B和C的值做成key-value的对象,整个数据处理完后,形成一个可以放进 HTML5 中的 <optgroup> 标签中的数据结构。下面是初始的 javascript 代码:
var technologyData = data.turbinesVO.technology;
var technologyList = new Array();
var stageCodeArray = new Array();
var lastFrameType = technologyData[0].frameTypeGrp;
for(var i=0;i<technologyData.length;i++){
if(technologyData[i].frameTypeGrp == lastFrameType){
var tempStageCode = {
"optionId" : lastFrameType+"/"+technologyData[i].stageCode,
"optionSn" : lastFrameType+" - "+technologyData[i].stageCode
};
stageCodeArray.push(tempStageCode);
}
else{
var tempFrameType = {
"groupName" : lastFrameType,
"optionList" : stageCodeArray
};
technologyList.push(tempFrameType);
stageCodeArray = new Array();
var tempStageCode = {
"optionId" : technologyData[i].frameTypeGrp+"/"+technologyData[i].stageCode,
"optionSn" : technologyData[i].frameTypeGrp+" - "+technologyData[i].stageCode
};
stageCodeArray.push(tempStageCode);
}
lastFrameType = technologyData[i].frameTypeGrp;
}
var tempFrameType = {
"groupName" : lastFrameType,
"optionList" : stageCodeArray
};
technologyList.push(tempFrameType);
这个算法是基于数据对象 technologyData 已经根据 frameTypeGrp 进行排序(在数据库已经排好序了)。
理解了这个算法后,经考虑形成了下面的java算法:
Map<String, Technology> unikTechs = new HashMap<String, Technology>();
Technology technology = null;
// turbinesVO.getTechnology() returns target data which being handled
for (TechnologyDTO tech : turbinesVO.getTechnology()) {
// fameType is the column A, that becomes group key and will put into auxiliary collection unikTechs
String fameType = tech.getFrameTypeGrp();
// check whether there is already a Technology with this given group key - "fameType"
if (unikTechs.keySet().contains(fameType)){
technology = unikTechs.get(fameType);
} else {
// this means this group key is first time to come
technology = new Technology();
technology.setGroupName(fameType);
// associate to the final returned object "result" by result.getTechs()
result.getTechs().add(technology);
// update auxiliary collection for future examination
unikTechs.put(fameType, technology);
}
// construct column B&C as key-value to an option for <optgroup>
String stageCode = tech.getStageCode();
Pair pair = new Pair();
pair.setOptionId(fameType + "/" + stageCode);
pair.setOptionSn(fameType + " - " + stageCode);
// append this option to optionList under group key - "fameType"
technology.getOptionList().add(pair);
}
对应的辅助类:
public class Technology implements Comparable<Technology>{
private String groupName;
private List<Pair> optionList = new ArrayList<Pair>();
@Override
public int compareTo(SiteTurbine o) {
return this.groupName.compareTo(o.groupName);
}
public String getGroupName() {
return groupName;
}
public void setGroupName(String groupName) {
this.groupName = groupName;
}
public List<Pair> getOptionList() {
return optionList;
}
public void setOptionList(List<Pair> optionList) {
this.optionList = optionList;
}
}
public class Pair{
private String optionId;
private String optionSn;
public String getOptionId() {
return optionId;
}
public void setOptionId(String optionId) {
this.optionId = optionId;
}
public String getOptionSn() {
return optionSn;
}
public void setOptionSn(String optionSn) {
this.optionSn = optionSn;
}
}
经过修改后,算法更容易懂,而且数据对象可以是无序的(即没有按 fameType 进行字典排序),而且比较优雅。:)