小弟要去除数据库中重复的内容,自己写了方法(如下),但是自己感觉效率太低,因为数据库中有几百万条的数据,求高手给一个高效率的方法。 List<String> list = new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
list.add("a");
list.add("c");
list.add("c");
list.add("c");
list.add("d");
for (int i = 0; i < list.size(); i++) {
for (int j = i+1; j < list.size(); j++) {
if(list.get(i).equals(list.get(j))){
list.remove(j);
j--;
}
}
}
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
list.add("a");
list.add("b");
list.add("c");
list.add("d");
list.add("a");
list.add("c");
list.add("c");
list.add("c");
list.add("d");
for (int i = 0; i < list.size(); i++) {
for (int j = i+1; j < list.size(); j++) {
if(list.get(i).equals(list.get(j))){
list.remove(j);
j--;
}
}
}
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
所有字段都相同吗?
直接用sqlplus或其他工具处理就好了
建议用多线程 分批更新
先查出有重复数据
然后分批删除数据
实际情况是这样,比如装User对象,去除名字相同的: List<User> list = 从数据库中查询的所有内容。
for (int i = 0; i < list.size(); i++) {
for (int j = i+1; j < list.size(); j++) {
if(list.get(i).getName().equals(list.get(j).getName())){
//这里要执行一条sql语句,删除数据库中 list.get(j)所代表的这条记录。
list.remove(j);
j--;
}
}
}
List<User> list = 从数据库中查询的所有内容。
List<User> list2 = new ArrayList<User>();
//第一,把list全放在list2中
for (User user : list) {
list2.add(user);
}
//第二,去除list中相同的
for (int i = 0; i < list.size(); i++) {
for (int j = i+1; j < list.size(); j++) {
if(list.get(i).getName().equals(list.get(j).getName())){
list.remove(j);
j--;
}
}
}
//第三,再把list2中的list全去掉,list2中剩下的就是那些相同的
list2.removeAll(list);
//第四,最后循环list2,把list2中所代表的记录通通执行sql删除
还有数据库在插入数据时本身要进行验证,几百万条的数据表要建索引。
还是放心交给SQL语句处理吧。话说这样的唯一字段,应该设计一个唯一索引或者唯一约束啊。
而且,某个字段保证唯一,那么如果其他字段不同,你该删除哪个呢?这应该是个问题。
import java.util.Iterator;class User{
String name;
int value;
User(String name, int value) {
this.name = name;
this.value = value;
}
public boolean equals(Object o) {
if (!(o instanceof User))
return false;
return hashCode() == o.hashCode();
}
public int hashCode() {
return name.hashCode();
}
public String toString() {
return String.format("name = %s, value = %d", name, value);
}
}public class test {
public static void main(String[] args) {
HashSet<User> set = new HashSet<User>();
User u1 = new User("aaa", 1);
User u2 = new User("bbb", 2);
User u3 = new User("aaa", 3);
set.add(u1);
set.add(u2);
set.add(u3);
Iterator<User> iter = set.iterator();
while (iter.hasNext())
System.out.println(iter.next());
}
}
输出:
name = aaa, value = 1
name = bbb, value = 2用HashSet的话,通过重写hashCode和equals函数来做到判定是否重复
写个oracle的sql在这里:
select * from t t1 where not exists (select 1 from t t2 where t2.c1 = t1.c1 and t2.rowid < t1.rowid);select * from (select t1.*, row_number() over(partition by c1 order by 1) rn from t t1) where rn = 1;
HashSet<User> set = new HashSet<User>();
set.addAll(list);
这样三句话就能解决了。set就是你想要的。前提是你要重写User的hashCode和equals方法。
但如果User是hibernate的POJO的话,hashCode和equals方法很重要,所以你按照你的这个想法重写的话,可能会让hibernate不能正常工作。所以建议你这样:
UserDTO extends User
然后重写UserDTO的hashCode和equals方法。再对list中的数据进行一下强制类型转换。
小弟根据3楼 4楼兄弟的提醒,直接在数据库层解决了,第一次发现sql语句原来如此的强大,挖哈哈:
delete from public.power1
where team in (select team from public.power1 group by team having count(team) > 1)
and id not in (select min(id) from public.power1 group by team having count(team )>1);同时为了分享学习成果,把我找到的贴出来,建议大家都去看看,sql语句写好了可以省很多麻烦:
http://laiba.tianya.cn/laiba/CommMsgs?cmm=27320&tid=2706139544684889786
写个oracle的sql在这里:
select * from t t1 where not exists (select 1 from t t2 where t2.c1 = t1.c1 and t2.rowid < t1.rowid);select * from (select t1.*, row_number() over(partition by c1 order by 1) rn from t t1) where rn = 1;
额,16楼的兄弟,你的强大的很生猛阿!小弟sql语句不太好,不太明白not exists , over , rn等的意思,麻烦给讲一讲
应该是database 后台直接输命令 select * into <newTable> from <yourTableName> group by name
not exists 不存在
sql中的over函数和row_number()函数配合使用,可生成行号。可对某一列的值进行排序,对于相同值的数据行进行分组排序
http://blog.csdn.net/dudongxiao/archive/2007/11/09/1876149.aspx