Java 优化两个列表的比较

Java 优化两个列表的比较,java,performance,grails,groovy,comparison,Java,Performance,Grails,Groovy,Comparison,我有两个联系人列表(A和B),来自SQL数据库。在我的应用程序中,我需要根据联系人姓名显示这些列表的比较表。如果姓名为a的联系人存在于列表a中,但不存在于列表B中,则联系人a的详细信息标记为绿色,在其旁边我有空白的红色空格(表示列表B中缺少条目)。如果联系人姓名存在于B中而不存在于a中,则B标记为绿色。如果联系人姓名存在于两个列表中,但地址不同,则两个联系人都标记为黄色 我正在生成CSV比较和分页接口 目前,我的非最佳解决方案将首先创建第三个列表,其中包含a和B中的所有联系人姓名,并删除重复项。

我有两个联系人列表(A和B),来自SQL数据库。在我的应用程序中,我需要根据联系人姓名显示这些列表的比较表。如果姓名为a的联系人存在于列表a中,但不存在于列表B中,则联系人a的详细信息标记为绿色,在其旁边我有空白的红色空格(表示列表B中缺少条目)。如果联系人姓名存在于B中而不存在于a中,则B标记为绿色。如果联系人姓名存在于两个列表中,但地址不同,则两个联系人都标记为黄色

我正在生成CSV比较和分页接口

目前,我的非最佳解决方案将首先创建第三个列表,其中包含a和B中的所有联系人姓名,并删除重复项。接下来(如果分页),我将应用偏移量+大小。最后,使用剩余条目,我将按联系人姓名(从新列表)搜索a和B,并调用一个比较方法,该方法将告诉我如何进行颜色标记

这对于我得到的数据量来说是可行的,最多4-5k,分页延迟2秒。虽然我知道这不是一个理想的解决方案,但想不出更好的解决方案。此外,我还获得了一些新功能(过滤器更改/添加/删除),这些功能在这种方法下无法最佳工作

我还可以用什么方法来解决这个比较问题

更新

控制器代码:

    //createCompareList() based on parameters generate HQL query and pull contacts from Contact table 
        def listA = createCompareList(params) 
        def listB = createCompareList(params)

        def unionList = listA.collect{it.details.name}.plus(listB.collect {it.details.name})
        unionList = unionList.unique()
        result.unionListSize = unionList.size()
        unionList.sort()
其余的比较在GSP中进行(这将移动到控制器,并在GSP中传递需要较少处理的内容)


C
联系人姓名
列举
名单B
${unionName}

如果您从SQL数据库获取数据,并且您的联系人列在不同的表中,您可以在他们的表之间执行
左联接。例如:

SELECT A.*, B.id 
FROM ContactsA A 
LEFT JOIN ContactsB B ON A.id = B.id;
并使用jdbc检索其结果。这些结果包含属于
ContactsA
的所有联系人,如果联系人位于列表
ContactsB
NULL
中,则还包含一个带有
id
的附加列。您可以使用该列来区分两个列表中出现的条目

编辑

如果您的两个列表是从同一个表中提取的,您可以始终在同一个表上执行thr
左联接
,参数化将条目拆分为两个列表的列:

例如,假设要按年龄拆分条目,则查询应为:

SELECT A.*, B.id 
FROM ContactsA A 
LEFT JOIN ContactsA B ON A.id = B.id AND B.age >= 18
WHERE A.age < 18;
选择A.*,B.id
来自ContactsA
A.id=B.id和B.age>=18上的左连接联系人A B
其中A.年龄<18岁;
结束编辑


如果您无法更改查询,并且已经有两个Java
List
s:
A
B
,检查联系人是否同时存在的最佳方法是从较短列表中构建一个集合,并使用该集合检查较长列表中的哪些元素不存在于较短列表中。

我的提示:使用
排序edSet
作为累加器。因此,您可以保存对
unique()
sort()
的调用,这两个调用都将遍历整个列表:

SortedSet unionList = new TreeList()
for( def a in listA ) unionList << a.details.name
for( def b in listB ) unionList << b.details.name
unionList // now it's unique and sorted in one sit
SortedSet unionList=新树列表()

对于(列表a中的def a)unionList,为了加快2个列表的比较,请使用集合。如果使用as哈希值,则联系人的姓名可以签入O(1),如果列表中有条目。如果是,请检查其他信息

Set<Contact> set_a = a.toSet
Set<Contact> set_b = b.toSet
foreach(e in (a union b))
  if(set_a contains e && !set_b contains e)
     //in a but not in b
  else if(!set_a contains e && set_b contains e)
     //in b but not in a
  else
     //in b and in a, check additional information for these elements
Set Set\u a=a.toSet
Set Set_b=b.toSet
foreach(e在(a和b))
if(集合a包含e&!集合b包含e)
//在a中,但不在b中
如果(!set_a包含e&&set_b包含e),则为else
//在b中但不在a中
其他的
//在b和a中,检查这些元素的附加信息
应该加快整个过程,因为比较便宜


这导致比较+构建集合的总体复杂性为O(2n)。

我不确定我是否正确理解您的要求,但我认为所有这些都可以通过查询在数据库端完成

根据我的说法,让db来处理比较,这比jdbc代码要快得多

A和B是联系人列表,在DB中都作为表格显示

Req1:A中不存在于B中的联系人列表

select id  <or required attrib> from A where id not in (select id from B)
select id  <or required attrib> from B where id not in (select id from A)
select A.id from A,B where A.id=B.id and A.addr<>B.addr
从A中选择id,其中id不在(从B中选择id)
这将是一个ID列表,仅在a中,将它们附加到java列表a中,颜色为绿色,因为您知道B中没有匹配的条目,请将B中的各个条目保持为空

Req2:B中独特联系人的类似内容

select id  <or required attrib> from A where id not in (select id from B)
select id  <or required attrib> from B where id not in (select id from A)
select A.id from A,B where A.id=B.id and A.addr<>B.addr
从B中选择id,其中id不在B中(从A中选择id)
两个列表中完全相反的内容,现在将此列表附加到B中