前言:如果数据量小的话两个for循环足以解决,博主因为项目中涉及到一个将近70w的List集合去重,刚开始用了两个for循环需要20秒的时间,后来发现这个方法可以只用不超过一秒的时间就能完成去重并且将相同对象的属性相加,下面贴出代码:
先根据要比较的属性排序,将他们放在一起,例如{a,b,c,a,d,b,c} ==> {a,a,b,b,c,c,d}
这样能节省遍历的时间
public static List<Student> toBusinessNameHeavyAndScore(List<Student> list) {
long a = System.currentTimeMillis();
Collections.sort(list, new Comparator<Student>() {
public int compare(Student o1, Student o2) {
return o1.getName().compareTo(o2.getName());
}
});
for (int ia = 0; ia < list.size(); ia++) {//加分去重
int count = 0; //计数器
for (int j = ia + 1; j < list.size(); j++) {
if (list.get(ia).getName().equals(list.get(j).getName())) {
count++;//n位和n+1位对比,如果相同,计数器应该+1
} else { break;}//如果不同,则说明相同的对象已经对比完(因为开始就已经进行了排序),则可以进行除重和重新计算,时间复杂度等于 }
}
int tempScore = list.get(ia).getScore();//取起始位置的分数
for (int j = 0; j < count; j++) {//这个count就是重复值的数量?
tempScore += list.get(ia + 1).getScore();//计数器记录了后面有几个相同的,循环count 起始位置+count(j) + 1
list.remove(ia + 1); // List是动态数组,循环count,删除i+1即可
}
list.get(ia).setScore(tempScore);//出重已经完成,重新赋值即可
}
Collections.sort(list, new Comparator<Student>() {
public int compare(Student o1, Student o2) {
if (o1.getScore() < o2.getScore()) {
return 1;
}
if (o1.getScore() == o2.getScore()) {
return 0;
}
return -1;
}
});
long b = System.currentTimeMillis();
System.out.println("@去重加分消耗时间:"+(b-a));
return list;
}
将相同属性的的下标记录下来, {a,b,b,b,c,c,d},举例遍历 b 的下标为1,遍历后得到三个相同的属性,用count记录下来,下面取第一个起始位置的属性也就是第一个 b(下标为1) 的属性,循环count, 重复对象的下标为 起始位置+count(j)+1
我这个还有一个分数,后面的排序是为了按照分数降序排列,可以忽略