Map的containskey方法使用哈希算法查找key是否存在,运算时间是常数;

List的contains方法是将元素在列表中遍历,运算时间和列表长度有关。

我使用两种不同SQL语句获取两种不同类型的结果集进行比较,发现两者差别很明显。

名称 类型 比较方法 耗时
两个含35,7282数据的map对比 map containsKey 101ms
两个含36,13962数据的list对比 list contains 46s455ms

至于Map包含的数据量略少于map,是因为存在重复key,map把它过滤掉了,这在结果集比较时有一小段是缺乏证明的,需要用另外的手段再验证。

代码:

package com.ufo.leftjoin;

import java.security.MessageDigest;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties; import org.apache.log4j.Logger; public class SqlComparator {
private static Logger log = Logger.getLogger(SqlComparator.class); public void compare() {
Connection conn = null;
Statement stmt = null; try {
Class.forName(DBParam.Driver).newInstance();
Properties pro = new Properties();
pro.setProperty("user", DBParam.User);
pro.setProperty("password", DBParam.Pswd); conn = DriverManager.getConnection(DBParam.DbUrl, pro);
stmt = conn.createStatement(); //compareUsingMap(stmt); compareUsingList(stmt);
} catch (Exception e) {
System.out.print(e.getMessage());
e.printStackTrace();
} finally {
try {
stmt.close();
conn.close();
} catch (SQLException e) {
log.error("Can't close stmt/conn because of " + e.getMessage());
}
}
} private void compareUsingMap(Statement stmt) throws SQLException {
long startMs = System.currentTimeMillis();
Map<String,DhItem> leftMap=getMapFrom(getLeftjoinSql(),stmt);
long endMs = System.currentTimeMillis();
log.info("It takes "+ms2DHMS(startMs,endMs)+" to get leftMap.");
int leftCount=leftMap.size();
log.info("There are "+toEastNumFormat(leftCount)+" records in leftMap."); startMs = System.currentTimeMillis();
Map<String,DhItem> notexistMap=getMapFrom(getNotExistSql(),stmt);
endMs = System.currentTimeMillis();
log.info("It takes "+ms2DHMS(startMs,endMs)+" to get notexistMap.");
int notexistCount=notexistMap.size();
log.info("There are "+toEastNumFormat(notexistCount)+" records in notexistMap."); startMs = System.currentTimeMillis();
List<DhItem> onlyInInnerLs=new ArrayList<DhItem>();
int count=0;
for(String key:notexistMap.keySet()) {
if(leftMap.containsKey(key)) {
count++;
}else {
DhItem dhItem=notexistMap.get(key);
onlyInInnerLs.add(dhItem);
}
} log.info("There are "+toEastNumFormat(count)+" records in two maps.");
log.info("There are "+toEastNumFormat(onlyInInnerLs.size())+" records only in notexistMap.");
endMs = System.currentTimeMillis();
log.info("It takes "+ms2DHMS(startMs,endMs)+" to complete comparison using map.");
} private void compareUsingList(Statement stmt) throws SQLException {
long startMs = System.currentTimeMillis();
List<DhItem> leftList=getListFrom(getLeftjoinSql(),stmt);
long endMs = System.currentTimeMillis();
log.info("It takes "+ms2DHMS(startMs,endMs)+" to get leftList.");
int leftCount=leftList.size();
log.info("There are "+toEastNumFormat(leftCount)+" records in leftList."); startMs = System.currentTimeMillis();
List<DhItem> notexistList=getListFrom(getNotExistSql(),stmt);
endMs = System.currentTimeMillis();
log.info("It takes "+ms2DHMS(startMs,endMs)+" to get notexistList.");
int notexistCount=notexistList.size();
log.info("There are "+toEastNumFormat(notexistCount)+" records in notexistList."); startMs = System.currentTimeMillis();
List<DhItem> onlyInInnerLs=new ArrayList<DhItem>();
int count=0;
for(DhItem item:notexistList) {
if(leftList.contains(item)) {
count++;
}else {
onlyInInnerLs.add(item);
}
} log.info("There are "+toEastNumFormat(count)+" records in two lists.");
log.info("There are "+toEastNumFormat(onlyInInnerLs.size())+" records only in notexistList.");
endMs = System.currentTimeMillis();
log.info("It takes "+ms2DHMS(startMs,endMs)+" to complete comparison using list.");
} private List<DhItem> getListFrom(String sql,Statement stmt) throws SQLException {
List<DhItem> list=new ArrayList<DhItem>(); ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
DhItem dhItem=new DhItem();
dhItem.order_no=rs.getString("order_no");
dhItem.shipper_code=rs.getString("shipper_code");
dhItem.vehicle_name=rs.getString("vehicle_name");
dhItem.vehicle_code=rs.getString("vehicle_code");
dhItem.reason_name_mobile=rs.getString("reason_name_mobile");
dhItem.status_name_mobile=rs.getString("status_name_mobile");
list.add(dhItem);
} return list;
} private Map<String,DhItem> getMapFrom(String sql,Statement stmt) throws SQLException {
Map<String,DhItem> map=new HashMap<String,DhItem>(); ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
DhItem dhItem=new DhItem();
dhItem.order_no=rs.getString("order_no");
dhItem.shipper_code=rs.getString("shipper_code");
dhItem.vehicle_name=rs.getString("vehicle_name");
dhItem.vehicle_code=rs.getString("vehicle_code");
dhItem.reason_name_mobile=rs.getString("reason_name_mobile");
dhItem.status_name_mobile=rs.getString("status_name_mobile");
map.put(toMD5(dhItem.toString()), dhItem);
} return map;
} private String getLeftjoinSql() {
StringBuilder sb = new StringBuilder();
sb.append(" SELECT ");
sb.append(" DH1.ORDER_NO, ");
sb.append(" DH1.SHIPPER_CODE , ");
sb.append(" DH1.VEHICLE_NAME, ");
sb.append(" DH1.VEHICLE_CODE , ");
sb.append(" DH1.REASON_NAME_MOBILE, ");
sb.append(" DH1.STATUS_NAME_MOBILE ");
sb.append(" from ");
sb.append(" DELIVERY_HISTORY DH1 ");
sb.append(" left JOIN DELIVERY_HISTORY DH2 on ");
sb.append(" DH1.SHIPPER_CODE = DH2.SHIPPER_CODE ");
sb.append(" and DH1.ORDER_NO = DH2.ORDER_NO ");
sb.append(" and DH2.UPDATED_DATETIME > DH1.UPDATED_DATETIME ");
sb.append(" where DH2.UPDATED_DATETIME IS NULL ");
sb.append(" and DH1.DISABLED_FLG = 0 ");
String sql = sb.toString();
return sql;
} private String getInnerSql() {
StringBuilder sb = new StringBuilder();
sb.append(" select ");
sb.append(" DH1.ORDER_NO, ");
sb.append(" DH1.SHIPPER_CODE , ");
sb.append(" DH1.VEHICLE_NAME, ");
sb.append(" DH1.VEHICLE_CODE , ");
sb.append(" DH1.REASON_NAME_MOBILE, ");
sb.append(" DH1.STATUS_NAME_MOBILE ");
sb.append(" from ");
sb.append(" DELIVERY_HISTORY dh1 , ");
sb.append(" (select SHIPPER_CODE,ORDER_NO,max(UPDATED_DATETIME) as utime from DELIVERY_HISTORY ");
sb.append(" group by SHIPPER_CODE,ORDER_NO) dh2 ");
sb.append(" where ");
sb.append(" dh1.SHIPPER_CODE=dh2.SHIPPER_CODE and ");
sb.append(" dh1.ORDER_NO=dh2.ORDER_NO and ");
sb.append(" dh1.UPDATED_DATETIME=dh2.utime and ");
sb.append(" dh1.DISABLED_FLG='0' "); String sql = sb.toString(); return sql;
} private String getNotExistSql() {
StringBuilder sb = new StringBuilder();
sb.append(" select ");
sb.append(" a.ORDER_NO, ");
sb.append(" a.SHIPPER_CODE , ");
sb.append(" a.VEHICLE_NAME, ");
sb.append(" a.VEHICLE_CODE , ");
sb.append(" a.REASON_NAME_MOBILE, ");
sb.append(" a.STATUS_NAME_MOBILE ,");
sb.append(" a.UPDATED_DATETIME");
sb.append(" from DELIVERY_HISTORY a");
sb.append(" where not exists(select 1 ");
sb.append(" from DELIVERY_HISTORY b");
sb.append(" where b.SHIPPER_CODE=a.SHIPPER_CODE and b.ORDER_NO=a.ORDER_NO and b.UPDATED_DATETIME>a.UPDATED_DATETIME)");
sb.append(" and a.DISABLED_FLG=0 "); String sql = sb.toString();
return sql;
} // 将整数在万分位以逗号分隔表示
public static String toEastNumFormat(long number) {
DecimalFormat df = new DecimalFormat("#,####");
return df.format(number);
} /**
* change seconds to DayHourMinuteSecond format
*
* @param startMs
* @param endMs
* @return
*/
private static String ms2DHMS(long startMs, long endMs) {
String retval = null;
long secondCount = (endMs - startMs) / 1000;
String ms = (endMs - startMs) % 1000 + "ms"; long days = secondCount / (60 * 60 * 24);
long hours = (secondCount % (60 * 60 * 24)) / (60 * 60);
long minutes = (secondCount % (60 * 60)) / 60;
long seconds = secondCount % 60; if (days > 0) {
retval = days + "d" + hours + "h" + minutes + "m" + seconds + "s";
} else if (hours > 0) {
retval = hours + "h" + minutes + "m" + seconds + "s";
} else if (minutes > 0) {
retval = minutes + "m" + seconds + "s";
} else {
retval = seconds + "s";
} return retval + ms;
} public static String toMD5(String key) {
char hexDigits[] = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
};
try {
byte[] btInput = key.getBytes();
// 获得MD5摘要算法的 MessageDigest 对象
MessageDigest mdInst = MessageDigest.getInstance("MD5");
// 使用指定的字节更新摘要
mdInst.update(btInput);
// 获得密文
byte[] md = mdInst.digest();
// 把密文转换成十六进制的字符串形式
int j = md.length;
char str[] = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = md[i];
str[k++] = hexDigits[byte0 >>> 4 & 0xf];
str[k++] = hexDigits[byte0 & 0xf];
}
return new String(str);
} catch (Exception e) {
return null;
}
} public static void main(String[] args) {
SqlComparator sc=new SqlComparator();
sc.compare();
}
}

输出:

2019-12-25 10:31:17,997  INFO [main] - It takes 2m36s81ms to get leftMap.
2019-12-25 10:31:18,002 INFO [main] - There are 35,7282 records in leftMap.
2019-12-25 10:33:57,147 INFO [main] - It takes 2m39s145ms to get notexistMap.
2019-12-25 10:33:57,147 INFO [main] - There are 35,7282 records in notexistMap.
2019-12-25 10:33:57,247 INFO [main] - There are 35,7282 records in two maps.
2019-12-25 10:33:57,247 INFO [main] - There are 0 records only in notexistMap.
2019-12-25 10:33:57,248 INFO [main] - It takes 0s101ms to complete comparison using map. 2019-12-25 10:44:22,695 INFO [main] - It takes 2m36s52ms to get leftList.
2019-12-25 10:44:22,700 INFO [main] - There are 36,1396 records in leftList.
2019-12-25 10:46:55,335 INFO [main] - It takes 2m32s634ms to get notexistList.
2019-12-25 10:46:55,335 INFO [main] - There are 36,1396 records in notexistList.
2019-12-25 10:47:41,789 INFO [main] - There are 0 records in two lists.
2019-12-25 10:47:41,790 INFO [main] - There are 36,1396 records only in notexistList.
2019-12-25 10:47:41,790 INFO [main] - It takes 46s455ms to complete comparison using list.

--END-- 2019-12-25 11:45

[Java数据结构]Map的contiansKey和List的contains比较的更多相关文章

  1. Java数据结构-------Map

    常用Map:Hashtable.HashMap.LinkedHashMap.TreeMap 类继承关系: HashMap 1)无序:  2)访问速度快:  3)key不允许重复(只允许存在一个null ...

  2. Java中常见数据结构Map之LinkedHashMap

    前面已经说完了HashMap, 接着来说下LinkedHashMap. 看到Linked就知道它是有序的Map,即插入顺序和取出顺序是一致的, 究竟是怎样做到的呢? 下面就一窥源码吧. 1, Link ...

  3. (7)Java数据结构--集合map,set,list详解

    MAP,SET,LIST,等JAVA中集合解析(了解) - clam_clam的专栏 - CSDN博---有颜色, http://blog.csdn.net/clam_clam/article/det ...

  4. Java遍历Map的3种方式

    package test; import java.util.Collection; import java.util.HashMap; import java.util.Map; import ja ...

  5. Java API —— Map接口

    1.Map接口概述         · 将键映射到值的对象         · 一个映射不能包含重复的键         · 每个键最多只能映射到一个值   2.Map接口和Collection接口的 ...

  6. Java中间Map List Set和其他收藏品

    Map List Set和其他收藏品: 一.概述 在JAVA的util包中有两个全部集合的父接口Collection和Map,它们的父子关系: +Collection 这个接口extends自 --j ...

  7. Java实现Map集合二级联动

    Map集合可以保存键值映射关系,这非常适合本实例所需要的数据结构,所有省份信息可以保存为Map集合的键,而每个键可以保存对应的城市信息,本实例就是利用Map集合实现了省市级联选择框,当选择省份信息时, ...

  8. (6)Java数据结构-- 转:JAVA常用数据结构及原理分析

    JAVA常用数据结构及原理分析  http://www.2cto.com/kf/201506/412305.html 前不久面试官让我说一下怎么理解java数据结构框架,之前也看过部分源码,balab ...

  9. (2)Java数据结构--二叉树 -和排序算法实现

    === 注释:此人博客对很多个数据结构类都有讲解-并加以实例 Java API —— ArrayList类 & Vector类 & LinkList类Java API —— BigDe ...

随机推荐

  1. Java—面向对象、类与对象、封装

    理解什么是面向过程.面向对象 面向过程与面向对象都是我们编程中,编写程序的一种思维方式. 面向过程的程序设计方式,是遇到一件事时,思考“我该怎么做”,然后一步步实现的过程. 面向对象的程序设计方式,是 ...

  2. Vue 自定义VueRouter-简版

    主要是思路,自己定义组件的时候可以借鉴 Vue-router的 类图 name options: ==> 记录构造函数中传入的对象,在 new VueRouter的时候传了一个对象( route ...

  3. CSS卡片右上角标记样式设计

    template <div class="each-one-in-list"> <div class="show-icon">进行中&l ...

  4. 【Spring注解驱动开发】使用@Autowired@Qualifier@Primary三大注解自动装配组件,你会了吗?

    写在前面 [Spring专题]停更一个多月,期间在更新其他专题的内容,不少小伙伴纷纷留言说:冰河,你[Spring专题]是不是停更了啊!其实并没有停更,只是中途有很多小伙伴留言说急需学习一些知识技能, ...

  5. MySQL查看正在执行的SQL进程

    查看正在执行的SQL进程: show processlist; 查出来之后, 可以使用下面的命令终止SQL进程: kill ${进程ID}

  6. Petya and Graph/最大权闭合子图、最小割

    原题地址:https://codeforces.com/contest/1082/problem/G G. Petya and Graph time limit per test 2 seconds ...

  7. PAT 2-05. 求集合数据的均方差(15)

    题目意思:求N个给定整数的均方差. 求平均值需要先转化为double类型,如果没转化会损失精度,造成错误. 代码如下: #include<iostream> #include<cma ...

  8. 基于 abp vNext 微服务开发的敏捷应用构建平台 - 设计构想

    许多中小企业的管理模式都是在自身的发展过程中不断摸索,逐步建立起来的,每一家都有其独有的管理模式,而且随着企业的不断发展,管理模式也在不断变化中.企业在发展壮大的过程中离不开信息化系统的支撑,企业在构 ...

  9. 结对项目:四则运算题目生成器(C)

    一.Github项目地址:https://github.com/Spartaright/myapp(合作人:梁天龙.赖佑铭) 二.PSP表格(如下图) 1.项目地址 PSP表格 PSP2.1 Pers ...

  10. 求X值问题

    这,其实是一道数学题,难就难在要把数学模型用编程语言实现,其中的规律如果看不出来就比较鸡肋,这类题可以算是智商题,做这类题千万不能紧张,血的教训. 题目描述 已知有整数x,x + 100为一个平方数. ...