java大数据集合对比。求高手帮忙下

qq_28905485 2016-10-24 04:00:44
现在查询数据有10W条数据使用一个
List<CheckDataDO> findList = collectDataChackDAO.findMpiInfoList("20150803", "20160803", null);接收
数据结构

创建了一个对象CheckDataDO 对象里面有 3个 属性
private String name;//姓名
private String phoneNumberSelf;//手机
private String idNo;//身份证
现在要做的是
使用findList 对比。规则:取一条数据和所有的数据进行对比,如果其中CheckDataDO 对象里面有2个属性值相等那么取出来放到一个集合里面。比如姓名相同,手机也相等那么把这条数据取出来
下面试我的代码
List<CheckDataDO> findList = collectDataChackDAO.findMpiInfoList("20150803", "20160803", null);

System.out.println(findList.size());
long start = (new Date()).getTime();
List<CheckDataDO> checklist = new ArrayList<>();
for (int i = 0; i < findList.size(); i++) {
for (int j = 0; j < findList.size(); j++) {
CheckDataDO checkDo = CheckDataDO.check(findList.get(i), findList.get(j));
if (checkDo != null) {
checklist.add(checkDo);
}
}
}

public static CheckDataDO check(CheckDataDO ycheckDataDO, CheckDataDO hcheckDataDO) {
CheckDataDO check = new CheckDataDO();
boolean flag = ycheckDataDO.equals(hcheckDataDO);
if (flag == true) {
check = null;
return check;
} else {
check = ycheckDataDO;
if (returnType == 1) {
check.setDescribe("身份证异常");
} else if (returnType == 2) {
check.setDescribe("姓名异常");
} else {
check.setDescribe("电话号码异常");
}
return check;
}
}

@Override
public boolean equals(Object obj) {
CheckDataDO checkDataDO = (CheckDataDO) obj;
String getFName = checkDataDO.getName();
String getPhone = checkDataDO.getPhoneNumberSelf();
String getIdNo = checkDataDO.getIdNo();
//如果是null或者“”则不需要对比
if(name == null && getFName == null
||phoneNumberSelf == null && getPhone == null
||idNo == null && getIdNo == null
||"".equals(name)&&"".equals(getFName)
||"".equals(phoneNumberSelf)&&"".equals(getPhone)
||"".equals(idNo)&&"".equals(getIdNo)
){
returnType = 0;
return true;
}
//判断是否相等
boolean nameFlag = judgeData(name, getFName);
boolean phoneFlag = judgeData(phoneNumberSelf, getPhone);
boolean idNoFlag = judgeData(idNo, getIdNo);
if (nameFlag == true && phoneFlag == true && idNoFlag == true) {
returnType = 0;
return true;
} else if (nameFlag == true && phoneFlag == true && idNoFlag == false) {
//身份证异常
returnType = 1;
return false;
} else if (nameFlag == false && phoneFlag == true && idNoFlag == true) {
//姓名异常
returnType = 2;
return false;
} else if (nameFlag == true && phoneFlag == false && idNoFlag == true) {
//电话号码异常
returnType = 3;
return false;
} else {
return true;
}

}

我重写了equals方法,现在的问题是我使用了2个循环造成效率非常慢。3W条数据要2分钟,请问谁有思路
...全文
528 8 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
浮云若水 2016-10-26
  • 打赏
  • 举报
回复
我在想你干嘛要这样实现?不能用存储过程实现?这不是带不带宽的问题?一个list中存10W然后再去循环,如果说你拿出来的这10W条数据没有一条匹配上的,然后还得再去取再去比较?前面的时间那你岂不是这时间就白白浪费在取数循环比较这里了?当然这是我的个人看法!
org_cy 2016-10-26
  • 打赏
  • 举报
回复
CheckDataDO重写equals和hashcode后,试试下面的这个试试看看还需要多少秒 List<CheckDataDO> result = new ArrayList<CheckDataDO>(new HashSet<CheckDataDO>(findList ));
nikyotensai 2016-10-25
  • 打赏
  • 举报
回复
引用 4 楼 qq_28905485 的回复:
[quote=引用 2 楼 qq_26508409 的回复:] for (int i = 0; i < findList.size(); i++) { for (int j = 0; j < findList.size(); j++) { CheckDataDO checkDo = CheckDataDO.check(findList.get(i), findList.get(j)); if (checkDo != null) { checklist.add(checkDo); } } } 你不觉得重复吗? 0和1,1和0;就浪费了,j从i+1开始吧
0和1比完后满足条件,把0 取出来,1和0比完也满足条件那就把1取出来,如果不这样,就会漏了1.[/quote] 比一次,两个都取出来不行吗
qq_28905485 2016-10-25
  • 打赏
  • 举报
回复
引用 2 楼 qq_26508409 的回复:
for (int i = 0; i < findList.size(); i++) { for (int j = 0; j < findList.size(); j++) { CheckDataDO checkDo = CheckDataDO.check(findList.get(i), findList.get(j)); if (checkDo != null) { checklist.add(checkDo); } } } 你不觉得重复吗? 0和1,1和0;就浪费了,j从i+1开始吧
0和1比完后满足条件,把0 取出来,1和0比完也满足条件那就把1取出来,如果不这样,就会漏了1.
bree06 2016-10-25
  • 打赏
  • 举报
回复
直接使用SQL在数据库实现逻辑部分试试看.取10W的网络带宽挻大的, 这部分开销没有必要.
create table TEST_CHECK_DATA
(
  mpiid        INTEGER not null,
  name         VARCHAR2(20),
  phone_number VARCHAR2(15),
  id_no        VARCHAR2(20)
); /* 建测试表*/
(select t1.mpiid, t1.name, t1.phone_number, t1.id_no from test_check_data t1 inner join ( /*name, phone_number*/
select name, phone_number, count(1) as cnt from test_check_data group by name, phone_number) t2 on t1.name = t2.name and t1.phone_number = t2.phone_number and t2.cnt >1)
union all 
(select t1.mpiid, t1.name, t1.phone_number, t1.id_no from test_check_data t1 inner join ( /*name, id_no*/
select name, id_no, count(1) as cnt from test_check_data group by name, id_no) t2 on t1.name = t2.name and t1.id_no = t2.id_no and t2.cnt >1)
union all
(select t1.mpiid, t1.name, t1.phone_number, t1.id_no from test_check_data t1 inner join ( /*id_no, phone_number*/
select id_no, phone_number, count(1) as cnt from test_check_data group by id_no, phone_number) t2 on t1.id_no = t2.id_no and t1.phone_number = t2.phone_number and t2.cnt >1)
如果还达不到要求的话, 可以先将phoneNumberSelf,idNo在数据库排好序, 这样我们只需要一个临时变量和一次循环即可取出二个及以上属性个数大于2的值. 不过建议这种逻辑还是在插库的时候提前处理, 每次这么查询一次都要进去这种逻辑处理很浪费时间, 首先增加一个字段, 在插入, 更新, 删除 数据的时候先判断新数据的属性是否存在2个以上, 如果存在就把这个新增的字段置1, 这样查询的时候只需要取出新增字段值为1的数据即可.
njabctc 2016-10-25
  • 打赏
  • 举报
回复
三楼正解,楼主的逻辑并没有问题,10w*10w是得算个几分钟。
nikyotensai 2016-10-24
  • 打赏
  • 举报
回复
for (int i = 0; i < findList.size(); i++) { for (int j = 0; j < findList.size(); j++) { CheckDataDO checkDo = CheckDataDO.check(findList.get(i), findList.get(j)); if (checkDo != null) { checklist.add(checkDo); } } } 你不觉得重复吗? 0和1,1和0;就浪费了,j从i+1开始吧
nikyotensai 2016-10-24
  • 打赏
  • 举报
回复
你取出一个和其他比较为毛要2个循环

67,549

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧