`
tomkoo
  • 浏览: 186225 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

List数据对比筛选,如何才能达到最佳效率?

 
阅读更多
在实际的开发中,经常会晕倒这样的问题,有两个List的数据,需要对这两个List的数据进行对比,然后筛选出需要的对象。

例如:财务中的对账,数据源一个是银行日记账(aList),一个是银行对帐单(bList),业务操作就是把两个List里面金额相同的记录筛选掉,剩下金额不相等的。

在实际开发中我目前知道有两个方式(假设两个List各有1000条数据):

1、最简单的就是用双重循环进行比较,虽然简单,但是如果两个List的数据量都很大,那么运行时间将成数量级增长。循环次数为1000*1000

2、把一个List通过循环放入Map中,把需要比较的字段作为Map的Key,然后循环另外一个List,到Map里面去匹配。

for(A a : aList){
   map.put(a.amount,a);
}

for(B b : bList){
   A a = map.get(b.amount);
   if(a==null){
      //a==null则说明没有同b匹配的项
   }else{
      //a!=null则说明匹配上了
   }
}


由于在Map中取数非常快,主要的耗时就在业务处理和循环上。循环次数为1000*2

但是第2种方法还是有不足的地方:

1、当比较的值有相同的时候,由于Key必须唯一,所以后面的值会覆盖掉前面的数据
2、当比较的内容比较复杂,或者是多项的时候,就比较难处理


我想在平时开发中大家应该都会遇到这样的问题吧,不知道大家有没有更好的方法来解决这个问题!!
分享到:
评论
12 楼 抛出异常的爱 2008-01-18  
要想对的快....要把list先排了序才可以...
用set treemap之类的东西存放数据
这样才不用每次遍历
11 楼 red008 2008-01-18  
把2个list都加到一个新的set中去,这个set里面就全是不重复的数据了。
代码只需要2行,看着也舒服。
10 楼 Godlikeme 2008-01-18  
tomkoo 写道
在实际的开发中,经常会晕倒这样的问题,有两个List的数据,需要对这两个List的数据进行对比,然后筛选出需要的对象。

例如:财务中的对账,数据源一个是银行日记账(aList),一个是银行对帐单(bList),业务操作就是把两个List里面金额相同的记录筛选掉,剩下金额不相等的。

在实际开发中我目前知道有两个方式(假设两个List各有1000条数据):

1、最简单的就是用双重循环进行比较,虽然简单,但是如果两个List的数据量都很大,那么运行时间将成数量级增长。循环次数为1000*1000

2、把一个List通过循环放入Map中,把需要比较的字段作为Map的Key,然后循环另外一个List,到Map里面去匹配。

for(A a : aList){
   map.put(a.amount,a);
}

for(B b : bList){
   A a = map.get(b.amount);
   if(a==null){
      //a==null则说明没有同b匹配的项
   }else{
      //a!=null则说明匹配上了
   }
}


由于在Map中取数非常快,主要的耗时就在业务处理和循环上。循环次数为1000*2

但是第2种方法还是有不足的地方:

1、当比较的值有相同的时候,由于Key必须唯一,所以后面的值会覆盖掉前面的数据
2、当比较的内容比较复杂,或者是多项的时候,就比较难处理


我想在平时开发中大家应该都会遇到这样的问题吧,不知道大家有没有更好的方法来解决这个问题!!


第一种方法, 两个列表金额为Key,List为Value往 HashMap里面放就可以了。O(2n)
这种问题自己思考下吧,不要总期望找现成的。
9 楼 hamlet 2007-10-17  
CollectionUtils 好像不能满足lz的需求吧,
lz的意思是按照数据对象的某一属性进行比较,
而CollectionUtils中 则是按照对象在内存中的Id进行比较,
得到的结果很有可能会不同,除非重写数据对象的equal()方法。
看看CollectionUtils 的getCardinalityMap方法和getFreq()方法就知道了
public static Map getCardinalityMap(final Collection col) {
        HashMap count = new HashMap();
        Iterator it = col.iterator();
        while(it.hasNext()) {
            Object obj = it.next();
            Integer c = (Integer)(count.get(obj));
            if(null == c) {
                count.put(obj,new Integer(1));
            } else {
                [b]count.put(obj,new Integer(c.intValue() + 1))[/b];
            }
        }
        return count;
    }


private static final int getFreq(final Object obj, final Map freqMap) {
        try {
            return ((Integer)([b]freqMap.get(obj)[/b])).intValue();
        } catch(NullPointerException e) {
            // ignored
        } catch(NoSuchElementException e) {
            // ignored
        }
        return 0;
    }
8 楼 lighter 2007-10-15  
phantomhu 写道

Collections是那个包里面的 java.util.Collections的sort不能用在Collection对象上啊

嗯,你说的对,可以强制转化一下,呵呵:
Collections.sort((List)union);
Collections.sort((List)intersection);
Collections.sort((List)disjunction);
Collections.sort((List)subtract);
7 楼 phantomhu 2007-10-15  
lighter 写道
tomkoo 写道
Comparable实现排序,比较时还是需要循环啊

Commons 里面可能有你想要的答案,看一下CollectionUtils类吧
String[] arrayA = new String[] { "1", "2", "3", "3", "4", "5" };
String[] arrayB = new String[] { "3", "4", "4", "5", "6", "7" };

List a = Arrays.asList( arrayA );
List b = Arrays.asList( arrayB );

Collection union = CollectionUtils.union( a, b );
Collection intersection = CollectionUtils.intersection( a, b );
Collection disjunction = CollectionUtils.disjunction( a, b );
Collection subtract = CollectionUtils.subtract( a, b );

Collections.sort( union );
Collections.sort( intersection );
Collections.sort( disjunction );
Collections.sort( subtract );


System.out.println( "A: " + ArrayUtils.toString( a.toArray( ) ) );
System.out.println( "B: " + ArrayUtils.toString( b.toArray( ) ) );
System.out.println( "Union: " + ArrayUtils.toString( union.toArray( ) ) );
System.out.println( "Intersection: " + 
                    ArrayUtils.toString( intersection.toArray( ) ) );
System.out.println( "Disjunction: " + 
                    ArrayUtils.toString( disjunction.toArray( ) ) );
System.out.println( "Subtract: " + ArrayUtils.toString( subtract.toArray( ) ) );


The previous example performs these four operations on two List objects, a and b, printing the results with ArrayUtils.toString( ):

A: {1,2,2,2,3,3,4,5}
B: {3,4,4,5,6,7}
Union: {1,2,2,2,3,3,4,4,5,6,7}
Intersection: {3,4,5}
Disjunction: {1,2,2,2,3,4,6,7}
Subtract: {1,2,2,2,3}




Collections是那个包里面的 java.util.Collections的sort不能用在Collection对象上啊
6 楼 tomkoo 2007-10-13  
抽出时间看了一下ColletionUtils类的源代码,发现,union,intersection,disjunction,subtract等方法的实现方式都是我前面提到的第二种方式,利用Map来进行一系列的比较操作。不过用得可比我的例子灵活多了。看了有种豁然开朗的感觉。

谢谢楼上的!
5 楼 tomkoo 2007-10-13  
lighter 写道
tomkoo 写道
Comparable实现排序,比较时还是需要循环啊

Commons IO 里面可能有你想要的答案,看一下CollectionUtils类吧
String[] arrayA = new String[] { "1", "2", "3", "3", "4", "5" };
String[] arrayB = new String[] { "3", "4", "4", "5", "6", "7" };

List a = Arrays.asList( arrayA );
List b = Arrays.asList( arrayB );

Collection union = CollectionUtils.union( a, b );
Collection intersection = CollectionUtils.intersection( a, b );
Collection disjunction = CollectionUtils.disjunction( a, b );
Collection subtract = CollectionUtils.subtract( a, b );

Collections.sort( union );
Collections.sort( intersection );
Collections.sort( disjunction );
Collections.sort( subtract );


System.out.println( "A: " + ArrayUtils.toString( a.toArray( ) ) );
System.out.println( "B: " + ArrayUtils.toString( b.toArray( ) ) );
System.out.println( "Union: " + ArrayUtils.toString( union.toArray( ) ) );
System.out.println( "Intersection: " + 
                    ArrayUtils.toString( intersection.toArray( ) ) );
System.out.println( "Disjunction: " + 
                    ArrayUtils.toString( disjunction.toArray( ) ) );
System.out.println( "Subtract: " + ArrayUtils.toString( subtract.toArray( ) ) );


The previous example performs these four operations on two List objects, a and b, printing the results with ArrayUtils.toString( ):

A: {1,2,2,2,3,3,4,5}
B: {3,4,4,5,6,7}
Union: {1,2,2,2,3,3,4,4,5,6,7}
Intersection: {3,4,5}
Disjunction: {1,2,2,2,3,4,6,7}
Subtract: {1,2,2,2,3}



还真的没有好好使用过CollectionUtils,谢谢!这就看去!
4 楼 lighter 2007-10-13  
tomkoo 写道
Comparable实现排序,比较时还是需要循环啊

Commons 里面可能有你想要的答案,看一下CollectionUtils类吧
String[] arrayA = new String[] { "1", "2", "3", "3", "4", "5" };
String[] arrayB = new String[] { "3", "4", "4", "5", "6", "7" };

List a = Arrays.asList( arrayA );
List b = Arrays.asList( arrayB );

Collection union = CollectionUtils.union( a, b );
Collection intersection = CollectionUtils.intersection( a, b );
Collection disjunction = CollectionUtils.disjunction( a, b );
Collection subtract = CollectionUtils.subtract( a, b );

Collections.sort( union );
Collections.sort( intersection );
Collections.sort( disjunction );
Collections.sort( subtract );


System.out.println( "A: " + ArrayUtils.toString( a.toArray( ) ) );
System.out.println( "B: " + ArrayUtils.toString( b.toArray( ) ) );
System.out.println( "Union: " + ArrayUtils.toString( union.toArray( ) ) );
System.out.println( "Intersection: " + 
                    ArrayUtils.toString( intersection.toArray( ) ) );
System.out.println( "Disjunction: " + 
                    ArrayUtils.toString( disjunction.toArray( ) ) );
System.out.println( "Subtract: " + ArrayUtils.toString( subtract.toArray( ) ) );


The previous example performs these four operations on two List objects, a and b, printing the results with ArrayUtils.toString( ):

A: {1,2,2,2,3,3,4,5}
B: {3,4,4,5,6,7}
Union: {1,2,2,2,3,3,4,4,5,6,7}
Intersection: {3,4,5}
Disjunction: {1,2,2,2,3,4,6,7}
Subtract: {1,2,2,2,3}

3 楼 tomkoo 2007-10-12  
Comparable实现排序,比较时还是需要循环啊
2 楼 kidd3166 2007-10-12  
你这样属于自定义对象集合,我曾经用过比较器来比较2个集合
上网查找一个关于Comparable,Comparator 的资料吧
1 楼 lovegiggs 2007-10-12  
可以考虑利用数据库资源来比较,写个存储过程来实现,通过内存来跑

对于存在差别的记录加上标记,然后就可一通过简单查询就可以得到

账单的平衡与否。

相关推荐

    List和Treemap排序实例及效率对比

    本资源提供了List对对象中的属性和TreeMap, String>对键值排序,并针对100w条数据排序,对比List和TreeMap, String>排序的效率。个人认为排序效率对比可以相信,但也可能存在不科学之处,还请高手给与指点,多多包涵...

    arraylist 和 list<T> 效率对比

    此外,由于ArrayList内部使用的是object[]数组,所以每次添加或删除元素时,如果超出当前容量,都需要创建新的数组并复制所有元素,这在大数据量操作时可能效率较低。 相比之下,List是C# 2.0引入的泛型集合,它...

    jQuery表格数据条件筛选代码

    在网页开发中,数据展示和检索是至关重要的环节,尤其在大数据量的场景下,条件筛选功能能够极大地提升用户体验。本篇文章将详细讲解如何利用jQuery实现一个高效的表格数据条件筛选功能。 首先,jQuery是一个轻量级...

    dotnet-使用Linq筛选满足数组条件的List集合

    描述“Linq_List_Contrast_Baseon_Array 使用Linq筛选满足数组条件的List集合”进一步明确了这个任务是对比和筛选基于数组条件的List元素。 Linq提供了多种查询操作符,例如Where、Select、OrderBy等,用于处理各种...

    c#list添加数据

    标题“c#list添加数据”指的是如何向已经实例化的`List&lt;T&gt;`对象中添加数据。描述中提到“list&lt;&gt;.count==0”的情况,即列表为空时,需要向列表中添加数据。下面我们将详细讲解如何操作。 首先,我们来看代码中的`...

    两个list比较 取不同的对象

    ### 两个List比较取不同的对象 在Java编程中,经常需要对两个`List`进行比较,找出它们之间的差异。这通常涉及到数据结构的理解、算法设计以及...在实际应用中,可以根据具体需求灵活调整这些技术点,以达到最佳效果。

    数据筛选和排序.zip

    在C#编程语言中,数据筛选和排序是数据库应用系统开发中的核心技能,尤其是在构建高效、用户友好的数据管理系统时。本教学资源"数据筛选和排序.zip"包含了S1课程中关于这一主题的第六章教学内容,包括演示案例、上机...

    List.removeAll() 方法的性能效率

    4. **替代方案**:有时候,预处理数据或使用不同的数据结构可以提高效率。例如,如果需要移除的元素是连续的,直接使用`subList()`和`clear()`可能更快。 5. **批量操作**:如果需要移除的元素列表较大,可以考虑先...

    MFC ListControl与Excel 数据导入导出

    在实际应用中,有时我们需要将ListControl中的数据与Excel文件进行交互,例如导入Excel数据到ListControl中展示,或者从ListControl导出数据到Excel文件。在VS2010这样的集成开发环境中,实现这种功能可以极大地提高...

    python如何在列表、字典中筛选数据

    在Python编程中,筛选数据是常见的操作,尤其是在处理列表、字典和集合等数据结构时。本篇文章将详细探讨如何在这些数据结构中筛选出符合特定条件的数据。 首先,我们来看如何在列表中筛选数据。在列表中筛选数据...

    准确的获取数据:数据筛选.pptx

    数据筛选是数据分析过程中的关键步骤,...熟练掌握Pandas的筛选技巧能极大地提高数据处理效率,确保分析结果的准确性。在实际操作时,根据数据特性和分析需求,灵活运用这些方法,能够使你的数据分析工作更加得心应手。

    关于Java中List对象的分页思想-按10个或者n个数对list进行分组

    * 在大规模数据处理时,使用List对象的分页思想可以提高处理效率。 * 在数据分页时,使用List对象的分页思想可以实现分页处理。 * 在批量处理时,使用List对象的分页思想可以实现批量处理。 List对象的分页思想是一...

    CSharp导出List数据到xml文件

    在C#编程中,将List数据导出到XML文件是一个常见的任务,特别是在处理数据存储、交换或序列化时。XML因其结构清晰、易于解析和跨平台兼容性而被广泛使用。下面我们将详细讨论如何实现这一功能,以及相关的重要知识点...

    Android 保存List数据(SharedPreferences)

    请注意,尽管可以通过上述方法保存List数据,但这并不是SharedPreferences的最佳实践。对于大量或复杂数据的存储,建议使用SQLite数据库或者Room库,或者考虑使用文件存储、ContentProvider等其他持久化方案。此外,...

    两个集合比较(新增、编辑、删除)

    本文将深入探讨如何比较两个集合,并关注在Java中使用List进行对比时的“新增”、“编辑”和“删除”操作。首先,我们需要理解集合的基本概念。集合是存储一组元素的数据结构,而List是一种有序的集合,允许重复元素...

    C#List集合分组winform把List分组

    描述中提到的“**再做List数据集合打印或数据绑定时,需要把List集合分组筛选**”意味着在处理List数据并准备显示或输出时,可能需要根据某些条件对数据进行分类,然后可能进一步筛选出特定的子集。这可以通过Linq的...

    详解Java多线程处理List数据

    这种操作可以将List数据分配给多个线程,每个线程处理一部分数据,从而提高程序的执行效率。 二、为什么需要Java多线程处理List数据? 在处理大规模数据时,使用单线程来处理List数据可能会导致程序执行速度慢,...

    Activity之间传递List数据

    然而,标准的Intent API并不直接支持传递大型数据集合,如List。本文将详细讨论如何在Android中实现Activity之间传递List数据。 首先,理解Intent的基本用法。Intent主要用于启动其他Activity或BroadcastReceiver,...

    java开发List提高效率

    Java 开发 List 提高效率 Java 开发中,List 是一个常用的数据结构,经常需要将 List 转换为逗号分隔的字符串,以便于...提高 List 转换效率需要选择合适的方法和数据结构,并合理使用 third-party 库和 Stream API。

    java list 对比工具类 java list 对比工具类

    java list 对比工具类 java list 对比工具类java list 对比工具类 java list 对比工具类java list 对比工具类 java list 对比工具类java list 对比工具类 java list 对比工具类

Global site tag (gtag.js) - Google Analytics