关于java中List的removeAll()方法删除大量数据时的效率问题

问题描述

现在遇到一个关于List的removeAll()方法的效率问题,现在有一个数据量很大的List A,目前数据量是186万多,要删除一个子的List B,数据量是6万多,现在想到的只有A.removeAll(B);但是整个过程要花15分钟左右,电脑配置也不错,DELL商务机。      在网上也搜了不少,找到最符合条件的一条信息(06年的贴) http://topic.csdn.net/t/20060904/18/4998018.html ,大体内容跟我遇到的情况差不多,最后那位大拿把问题解决了,但是不太理解,就是简单的说“native method”方法。我对C这一块不熟,大家有没有遇到过这类问题,交流一下吧...   问题补充:<div class="quote_title">wangqj 写道</div><div class="quote_div">你最好把你存入list的数据是什么特点的贴出来,可以根据你的数据的特点重写removeAll方法</div><br />集合元素是Integer数组:List&lt;Integer[]&gt;

解决方案

public static List removeAll(List a,List b){LinkedList c=new LinkedList(a);//大集合用LinkedList HashSet s=new HashSet(b);//小集合用HashSet Iterator iter=c.iter;while(iter.hasNext()){if(s.contains(iter.next()){iter.remove();}}return c;}随手敲的,没编译过,估计内存开销挺大的
解决方案二:
引用集合元素是Integer数组:List<Integer[]> 集合里居然放的是数组,比较集合元素又要增加复杂度了。数组是否有序?比较两个数组相等的条件有要求吗?(所有下标对应的数组元素都相同,还是只要求数组包含相同元素)。
解决方案三:
我建议把Integer[]封装为一个对象class Compare{private int[] data;//get setpublic Compare(int[] n){ this.data =n; //jdk默认使用归并,根据数据的特性做出优化 Arrays.sort(data); } //重写equals @override public boolean(Compare c){ if(c.getData.length!=this.data.length) return false; for(int i=0;i<data.length;i++){ if(c.getData[i]!=data[i]) return fasle; } return true; } //重写hashcode public int hashcode(){ //最好将数据散列开 //... }}
解决方案四:
而且有可能慢不是慢在你remove上,而是gc上建议加大XMX
解决方案五:
为什么不用hashset呢
解决方案六:
方法重写
解决方案七:
你最好把你存入list的数据是什么特点的贴出来,可以根据你的数据的特点重写removeAll方法
解决方案八:
刚才测试了一下效果还不错:public static void main(String[] args) {int n = 1000000;int m = 10000;ArrayList<Integer> a = new ArrayList<Integer>(n);ArrayList<Integer> b = new ArrayList<Integer>(m);for (int i = 0; i < n; i++) {a.add(RandomUtils.randInt(n));//随机数}for (int i = 0; i < m; i++) {b.add(RandomUtils.randInt(n));}long time = System.currentTimeMillis();ArrayList<Integer> c = removeAll(a, b);time = System.currentTimeMillis() - time;System.out.println(time);//31044ms,31秒System.out.println(c.size());}
解决方案:
这个需要根据你自己的业务逻辑,自己实现一个算法,写一个集合类,覆盖arraylist的remove方法
解决方案:
很早以前研究过,我的方案是先把listA和listB用快速排序算法排好序,然后再比较删除,这样的时间复杂度就是O(n)(不算快速排序的时间),空间复杂度是O(n+m),牺牲内存换时间。
解决方案:
分析源码:引用 public boolean removeAll(Collection<?> c) {boolean modified = false;Iterator<?> e = iterator();while (e.hasNext()) { if (c.contains(e.next())) {e.remove();//如果是LinkedList,这步删除操作会快很多modified = true; }}return modified; }如果listA是LinkedList它的时间复杂度最差情况是O(n*m),n和m分别是listA和listB的size。如果是ArrayList它的时间复杂度最差情况就是O(n*n*m)。

时间: 2024-08-31 00:03:31

关于java中List的removeAll()方法删除大量数据时的效率问题的相关文章

《Android的设计与实现:卷I》——第2章2.4 在Java中调用JNI实现方法

2.4 在Java中调用JNI实现方法 本节介绍如何在Java中调用JNI实现方法.JNI数据类型转换.JNI方法命名规则,以及JNI方法签名规则. 2.4.1 Java数据类型与JNI数据类型转换 Java中调用Native方法传递的参数是Java类型的,这些参数需要经过Dalvik虚拟机转化为JNI类型才能被JNI层识别.下面分基本类型和引用类型介绍这种转化关系. 1.基本类型转化关系 表2-1列出了基本类型的转化关系. 2.引用类型转化关系 JNI的引用类型定义了九种数组类型,以及jobj

在Java中进行事务处理的方法

摘要 本文介绍在Java中进行事务处理的方法,通过实例分别讲述了如何采用JavaBean.Ejb组件实现J2EE应用服务器支持的JDBC事务.JTA(Java Transaction API)事务. 关键词 JavaBean,EJB, 数据库,事务处理,JTA JavaBean JavaBean是用Java语言编写的与平台无关的组件.它是描述Java的软件组件模型,有点类似于Microsoft的COM组件的概念.在Java模型中,通过JavaBean可以无限扩充Java程序的功能,通过JavaB

java中如何让setText方法读取指定标签数据的时候特意空出一点点空间

问题描述 java中如何让setText方法读取指定标签数据的时候特意空出一点点空间 如何让setText方法读取指定标签数据的时候特意空出一点点空间java当中 解决方案 http://zhidao.baidu.com/link?url=znfx-j9HEz7fJS4EcXcc-gX096uqEKQMTQo4vBNrc9bhRAlFHGGxkAP8cPTOkATWxy3DqxQwhBwFAscWkNPxe_,用空字符串占位置看看可不可以也就是字符串前面有空格,后面有空格. 解决方案二: 使用全

java中String的一些方法深入解析

以下是对java中String的一些方法进行了详细的分析介绍,需要的朋友可以参考下   1.public String(char[] c,begin,length).从字符数组c的下标begin处开始,将长度为length的字符数组转换为字符串. begin与length可以省略,即将字符数组c转换为字符串.另:字符数组可改为字节数组byte[] b.char[] c=new char[]{'j','y','6','a','4','t','9'}; String s1=new String(c)

java中final 变量作为方法的参数?怎么理解?见下面代码

问题描述 java中final 变量作为方法的参数?怎么理解?见下面代码 class NiMingLei { public static void main(String[] args) { Outer out= new Outer(); out.function(7); out.function(8); } } class Outer { static int y=4; void function(final int a) { class Inter { void method() { Sys

java中一个类的方法与方法之间可以有联系,也可以相互孤立吗

问题描述 java中一个类的方法与方法之间可以有联系,也可以相互孤立吗 java中一个类的方法与方法之间可以有联系,也可以相互孤立吗什么情况要孤立,什么情况要有联系呢 解决方案 看需求.比如说class A{ float get长度() { ... } float get宽度() { ... } float get面积() { return get长度()*get宽度(); }}这里就需要调用另外两个方法 解决方案二: 现在还有人有这玩意嘛 解决方案三: 类的方法主要是对属性的一些操作,方法作用

java语法-java中如何在其他方法的方法体里面初始化一个非静态public方法

问题描述 java中如何在其他方法的方法体里面初始化一个非静态public方法 java中如何在其他方法的方法体里面初始化一个非静态public方法 如何判断一个方法是不是静态方法, 解决方案 方法里面弄方法,,那是匿名类用的,,除此之外一般没这么用

java中 的变量在方法间的传递权限问题

问题描述 java中 的变量在方法间的传递权限问题 我现在定义了方法1(),在该方法里用了scanner获取了一个整数a,对这个整数进行了相关操作,返回了一个字符串s,但是我现在定义了一个方法2(),该方法要接收方法1()返回的字符串s,该方法同时也要用到方法1()中scanner获取的那个整数a,进行操作后返回一个整数b(b用main()函数接收),那么问题就来了,方法1只能返回一个字符串s,那么方法2()怎么获取方法1()的那个用scanner接收到的整数呢?我的想法是将方法1()中的sca

java中的类的方法的调用的问题

问题描述 java中的类的方法的调用的问题 新人初学java,有些概念不是很懂,还望各位能帮帮忙,谢谢 在java中,我知道静态方法(变量)可以直接类名.调用,而不用再创建对象, 但是我在学习枚举时遇到这样一个问题: public enum WeekDay{ MON,TUE,WEB,THU,FIR,SAT } public class TestEnum{ public void static main(String [] ,args){ WeekDay today = WeekDay.SAT;