关于两个List的增量高效比较

        之前遇到如何能高效的比较两个List的增量的问题,由于时间紧迫最起初的方式也是最原始的,就是使用各循环对比两个List两次并设置标示符的方式来进行比较。在两个List的数据量较小的时候,这种方式对效率的影响不会很明显,但当数量级达到一定程度的时候,效率问题就会浮出水面。想到Map集合Key值的唯一性,是否可以使用重写某个对象的equals()方法的方式来比较两个对象的一致性,再将对象放入Map中,相同的对象就修改该Key的Value,不同的以新的Key和Value插入Map,再通过Map的相关方法,就可以拿到两个List的增量。

        首先,先建立一个UserInfo的对象,并重写他的equals()方法,这里,我只是通过UserInfo的name属性来比较两个UserInfo是否相同。UserInfo的代码如下:

/**
 * Copyright (C) 2012  http://blog.csdn.net/Just_szl
 * 
 * 修订历史记录:
 * 
 * Revision	1.0	2013-6-19 Geray  创建。
 * 
 */
package com.geray.CompareDifferenceBetweenTowCollections;

/**
 * 
 * @author <a href="mailto:just_szl@hotmail.com"> Geray</a>
 * @version 1.0,2013-6-19 
 */
public class UserInfo {
	
	private String name;
	private int age;
	private String address;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}
	
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		UserInfo other = (UserInfo) obj;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
	
}
         然后建立比较的方法,先建立一个原始的比较方法compareDifferenceBetweenTwoArray(),也就是利用循环的方式比较两个List的增量。再使用Map的方式比较两个List的增量。ComDifClass代码如下:
/**
 * Copyright (C) 2012  http://blog.csdn.net/Just_szl
 * 
 * 修订历史记录:
 * 
 * Revision	1.0	2013-6-19 Geray  创建。
 * 
 */
package com.geray.CompareDifferenceBetweenTowCollections;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 
 * @author <a href="mailto:just_szl@hotmail.com"> Geray</a>
 * @version 1.0,2013-6-19 
 */
public class ComDifClass {

	/** 
	 * 最初的方式比较两个List的增量
	 * @param list1 原有的List
	 * @param list2 将要比较的List
	 */
	public static void compareDifferenceBetweenTwoArray(List<UserInfo> list1, List<UserInfo> list2){
		long currTime = System.currentTimeMillis();
		List<UserInfo> removeList = new ArrayList<UserInfo>();
		List<UserInfo> addList = new ArrayList<UserInfo>();
		loop1:for(int i = 0; i < list1.size() ; i++){
			boolean isExisted = false;
			UserInfo u1 = list1.get(i);
			for(int j = 0 ; j < list2.size() ; j++){
				UserInfo u2 = list2.get(j);
				if(u1.equals(u2)){
					isExisted = true;
					continue loop1;
				}
			}
			if(!isExisted){
				removeList.add(u1);
			}
		}
		
		for(int i = 0; i < list2.size() ; i++){
			boolean isExisted = false;
			UserInfo u1 = list2.get(i);
			loop2:for(int j = 0 ; j < list1.size() ; j++){
				UserInfo u2 = list1.get(j);
				if(u1.equals(u2)){
					isExisted = true;
					continue loop2;
				}
				
			}
			if(!isExisted){
				addList.add(u1);
			}
		}
		
		long endTime = System.currentTimeMillis();
		System.out.println("删除数据大小:"+ removeList.size());
		System.out.println("新增数据大小: " + addList.size());
		System.out.println("方法所用时间:"+(endTime-currTime)+"毫秒");
	}
	
	/**
	 * 修改后比较两个List的异同
	 * @param list1 原有的List
	 * @param list2 将要比较的List
	 */
	public static void compareDifferenceBetweenTwoArray2(List<UserInfo> list1, List<UserInfo> list2){
		long currTime = System.currentTimeMillis();
		//此处是对效率的进一步优化,将Size较大的List先放入Map中,
		boolean listIsChanged = false;
		List<UserInfo> maxList = list1;
		List<UserInfo> minList = list2;
		if(list1.size()<list2.size()){
			listIsChanged = true;
			maxList = list2;
			minList = list1;
		}
		Map<UserInfo,Integer> targetMap = new HashMap<UserInfo,Integer>();
		//将较大的List放入Map中,并将其value设为1
		for(UserInfo u : maxList){
			targetMap.put(u, 1);
		}
		//将较小的List放入Map中,如果存在则将其value设置为2,如果不存在则将其value设为-1
		for(UserInfo u : minList){
			boolean isExisted = targetMap.containsKey(u);
			if(isExisted){
				targetMap.put(u, 2);
			}else{
				targetMap.put(u, -1);
			}
		}
		long middleTime = System.currentTimeMillis();
		List<UserInfo> removeList = new ArrayList<UserInfo>();
		List<UserInfo> addList = new ArrayList<UserInfo>();
		
		if(listIsChanged){
			for(Map.Entry<UserInfo, Integer> entry : targetMap.entrySet()){
				 if(entry.getValue() == 1){
					addList.add(entry.getKey());
			    }else if(entry.getValue() == -1){
			    	removeList.add(entry.getKey());
			    }
			 }
		}else{
			for(Map.Entry<UserInfo, Integer> entry : targetMap.entrySet()){
				 if(entry.getValue() == 1){
					removeList.add(entry.getKey());
			    }else if(entry.getValue() == -1){
			    	addList.add(entry.getKey());
			    }
			 }
		}
		
		
		System.out.println("当前Map大小:"+targetMap.size());
		System.out.println("删除数据大小:"+ removeList.size());
		System.out.println("新增数据大小: " + addList.size());
		long endTime = System.currentTimeMillis();
		
		System.out.println("抽取前所用时间:"+(middleTime-currTime)+"毫秒");
		
		System.out.println("方法所用时间:"+(endTime-currTime)+"毫秒");
		
	}
	
	
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		List<UserInfo> list1 = new ArrayList<UserInfo>();
		List<UserInfo> list2 = new ArrayList<UserInfo>();
		for(int i = 0 ; i <10000 ; i++){
			UserInfo u1 = new UserInfo();
			u1.setName("S"+i);
			UserInfo u2 = new UserInfo();
			u2.setName("S"+i*2);
			list1.add(u1);
			list2.add(u2);
		}
		
		ComDifClass.compareDifferenceBetweenTwoArray(list1, list2);
		System.out.println("--------------华丽的分割线---------------");
		ComDifClass.compareDifferenceBetweenTwoArray2(list1, list2);
	}

}

           下面看一下两种方式对效率的提升。

          



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值