小弟要去除数据库中重复的内容,自己写了方法(如下),但是自己感觉效率太低,因为数据库中有几百万条的数据,求高手给一个高效率的方法。 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));
}

解决方案 »

  1.   

    不用ArrayList,用HashSet不就行了吗。
      

  2.   

    你的数据库表所有记录重复时什么概念?
    所有字段都相同吗?
    直接用sqlplus或其他工具处理就好了
      

  3.   

    如果你要讲究高效率,就不应该到运用程序中实现,应当在数据层实现。   Select distinct ... from ..
      

  4.   

    2楼不好意思,实际上数据库中不是简单的字符串,我写的只是一个例子,实际中ArrayList要装对象的,最后只是比较对象中的某个字段是否相等,用set集合并不能去除重复的,也想用map,但是如果用map,就要把数据库中内容全部清空,然后再把map中的内容全部插入数据库,还是感觉效率低。
      

  5.   

    set是不包含重复元素的,你可以重写compareTo函数
      

  6.   

    几百万条数据如果用sql语句去执行的话   很可能死掉
    建议用多线程 分批更新
    先查出有重复数据
    然后分批删除数据
      

  7.   

    我再讲的详细些:
    实际情况是这样,比如装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--;
                    }
                }
            }
      

  8.   

    LZ,放到List你同样删不得数据库的记录,除非是唯一ID,干吗这么费劲呢,封装了半天又要删掉,直接在数据库搞了...
      

  9.   

    9楼的意思我明白  分四部:
            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删除
      

  10.   

    用ArrayList肯定不行,建议直接从数据库方面着手解决问题。
    还有数据库在插入数据时本身要进行验证,几百万条的数据表要建索引。
      

  11.   

    几百万数据载入到列表中处理?程序会死掉的。不是失去响应,而是内存不足。
    还是放心交给SQL语句处理吧。话说这样的唯一字段,应该设计一个唯一索引或者唯一约束啊。
    而且,某个字段保证唯一,那么如果其他字段不同,你该删除哪个呢?这应该是个问题。
      

  12.   

    import java.util.HashSet;
    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函数来做到判定是否重复
      

  13.   

    当然是用sql解决啦,想想看,从内存方面考虑,需要删除的记录根本不用查出来,也就不用传回到前端,不用arraylist。几百万条数据不算大,java还死不了,但是不划算。你能保证你写的去重算法有数据库自己的实现高效吗
    写个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; 
      

  14.   

    List<User> list = 从数据库中查询的所有内容。
    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中的数据进行一下强制类型转换。
      

  15.   

    可以结贴了 兄弟们!感谢15楼的兄弟。
    小弟根据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
      

  16.   

    当然是用sql解决啦,想想看,从内存方面考虑,需要删除的记录根本不用查出来,也就不用传回到前端,不用arraylist。几百万条数据不算大,java还死不了,但是不划算。你能保证你写的去重算法有数据库自己的实现高效吗
    写个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等的意思,麻烦给讲一讲
      

  17.   

    database 后台直接输命令select * into from <yourTableName> group by name
      

  18.   

    刚才写错了
    应该是database 后台直接输命令 select * into <newTable> from <yourTableName> group by name
      

  19.   


    not exists  不存在
    sql中的over函数和row_number()函数配合使用,可生成行号。可对某一列的值进行排序,对于相同值的数据行进行分组排序
      

  20.   

    完全支持用sql语句解决重复记录问题,SQL语句可参考:
    http://blog.csdn.net/dudongxiao/archive/2007/11/09/1876149.aspx
      

  21.   

    这个问题很纠结!如果我要取整张表的所以字段,按某一列去掉重复行!怎么做 ?distinct 貌似不行!只能读出重复项的那一行!