Java实现两个csv文件的对比_Java实现CSV文件差异对比 | 学步园

在项目中经常会遇到使用CSV文件,比如从HR中得到的文件拿到其它地方去处理,实际会需要得到当前和上次文件中的差异,比如:添加,删除,修改, 那么如何来实现呢,可能有很的方法,在这里我说一下我的实现方法而且已投入实际使用。

首先, CSV文件典型以,分隔,当然还有其它的字符,由很多列的属性和属性值组成,那么两个文件变化之后,通常会是怎样的情况呢,

比如:添新的一行,删除已有一行,修改已有行某些值,没有任何变化。

所以实现思路是: 关键之一是能够找一个东西来唯一标识每一行,在这里我用的把某几个字段组合来作为ID,有了这个后就好办法,读取两个文件并把ID计算出来,但还有一个事情就是文件都读进来了,应该如何来决定添加,删除,修改呢,前面说了既然有了ID,那么拿去比较:

ID in old not in new   - > delete

ID in new not in old -> add

ID in both old and new -> modify

example:

old:

value1,value2,value3

test1,test2,test3

new:

hello,world,haha

value1,value2,value4

delta:

A, hello,world,haha

M, value1,value2,value4

D, test1,test2,test3

在修改情况下还要去判断修改了哪些值。使用Java的情况下,我的做法是读取两个文件然后封装为Entry, 再把entry存入Map(ID, Entry)中,然后再做比较,从左到右决定添加和修改,从右到左决定删除,使用Map的key,value查找特性,当然了比较结束后要把Delta数据写到新的csv文件中,目前处理8000行左右的时间远在1s内。下面是比较的代码片断

/**

* Compare the two Map then return the delta entry list

* @param input Map input Map where stored the entry and ID

* @param previous Map previous Map

*/

publicList deltaEntryList(Map input, Map previous){

List deltaList = newArrayList();

Iterator iterInput = input.entrySet().iterator();

Util.log("debug","Compare input with previous");

while(iterInput.hasNext()) {

Map.Entry entry = (Map.Entry) iterInput.next();

Object keyInput = entry.getKey();

Object valInput = entry.getValue();

//For Add

if( !previous.containsKey(keyInput) ){

Entry deltaAdd = (Entry)valInput;

deltaAdd.setOperation(Entry.OP_ADD);

deltaList.add(deltaAdd);

Util.log("debug","Add -> "+ deltaAdd.getID());

}else{//For Modify

Entry inputEntry = (Entry)valInput;

Entry previousEntry = (Entry)previous.get(keyInput);

List inputEntryList = inputEntry.getValueList();

List previousEntryList = previousEntry.getValueList();

booleanisMod =false;

for(intlistIndex =0; listIndex 

if( !previousEntryList.contains( inputEntryList.get(listIndex) ) ){

isMod = true;

break;

}

}

if(isMod){

inputEntry.setOperation(Entry.OP_MODIFY);

deltaList.add(inputEntry);

Util.log("debug","Modify -> "+ inputEntry.getID());

}

}

}

//For Delete from previous to input

Iterator iterPrevious = previous.entrySet().iterator();

while(iterPrevious.hasNext()) {

Map.Entry entry = (Map.Entry) iterPrevious.next();

Object keyPrevious = entry.getKey();

Object valPrevious = entry.getValue();

if( !input.containsKey(keyPrevious) ){

Entry deltaDel = (Entry)valPrevious;

deltaDel.setOperation(Entry.OP_DELETE);

deltaList.add(deltaDel);

Util.log("debug","Delete -> "+ deltaDel.getID());

}

}

Util.log("debug","Delta Entry size : "+ deltaList.size());

returndeltaList;

}

至于比较的方法,我认为使用Set的特性应该也可以实现。目前的实现可能还会有一些问题,仍需继续改进。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值