在项目中经常会遇到使用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的特性应该也可以实现。目前的实现可能还会有一些问题,仍需继续改进。

Java实现两个csv文件的对比_Java实现CSV文件差异对比相关推荐

  1. java如何处理csv文件上传_java处理csv文件上传示例

    前言:示例只是做了一个最最基础的上传csv的示例,如果要引用到代码中去,还需要根据自己的业务自行添加一些逻辑处理. ReadCsvUtil工具类 package com.hanfengyeqiao.g ...

  2. java上传csv文件上传_java处理csv文件上传示例详解

    前言:示例只是做了一个最最基础的上传csv的示例,如果要引用到代码中去,还需要根据自己的业务自行添加一些逻辑处理. readcsvutil工具类 package com.hanfengyeqiao.g ...

  3. java 自定义文件后缀名_Java 的源代码文件的扩展名是( )。_学小易找答案

    [单选题]在 Java 语言中,哪一个包中的类是自动导入的?( ) [填空题]static 方法中只 能 引 用 类型的数 据 成员和 类型的成 员 方法;而 非 static 类 型 的 方 法中 ...

  4. java实现对大文件切割下载_Java实现大文件的切割与合并操作示例

    Java实现大文件的切割与合并操作示例 发布时间:2020-09-27 02:25:08 来源:脚本之家 阅读:99 作者:HiBoyljw 本文实例讲述了Java实现大文件的切割与合并操作.分享给大 ...

  5. java资源文件获取属性_Java读写资源文件类Properties

    Java中读写资源文件最重要的类是Properties 1) 资源文件要求如下: 1.properties文件是一个文本文件 2.properties文件的语法有两种,一种是注释,一种属性配置. 注  ...

  6. java 调用 swf 文件上传_java SpringMvc 实现文件在线预览(openoffice+swftools+flexpaper)

    项目需求:服务器接受的文件当下只能下载之后才能浏览内容,现需要后台能在线浏览到文件内容,避免繁琐无用文件下载操作. 通过几天网上资料搜索,目前免费的在线预览开发技术使用最多还是(openoffice+ ...

  7. java读取文件并输出_java读取txt文件并输出结果

    这篇文章主要介绍了java读取txt文件并输出结果,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 描述: 1.java读取指定txt文件并解析 文件 ...

  8. java获取两个时间的间隔天数_java获取两日期的间隔天数

    这是我程序中用到的方法,传入的日期格式,可根据本身的须要做相应的改变.java /** * 读取两个日期之间的天数 * @param begin yyyy-mm-dd * @param end yyy ...

  9. java搜索文件夹中文件是否存在_java中判断文件文件夹是否存在的方法(附代码)...

    1.判断文件夹是否存在,不存在则创建:(java相关视频教程推荐:java视频教程)File folder = new File("d:est1est2"); if (!folde ...

  10. java列出文件正则过滤_JAVA正则表达式过滤文件的实现方法

    java正则表达式过滤文件的实现方法 正则表达式过滤文件列表,听起来简单,如果用java实现,还真需要一番周折,本文简析2种方式 1.适用于路径确定,文件名时正则表达式的情况(jdk6的写法) Str ...

最新文章

  1. 【iOS】Socket/TCP 通信 发送 NSString 字符串格式数据
  2. 让用VS2012/VS2013编写的程序在XP中顺利运行
  3. 用 easy-json-schema 代替 json-schema 吧
  4. c语言入门数组,C语言入门之数组(2)
  5. [sybase]自动增长字段创建方法
  6. dategurd oracle_Oracle 时间和日期处理
  7. Python - 遍历列表时删除元素的正确做法
  8. python 怎么调用 矩阵 第几行_python工厂第19层 多重列表1
  9. 中小企业用户如何选择简单进销存软件?
  10. 安装报错_Mysqlclient安装报错的3种情况
  11. 拓端tecdat|R语言使用Profviz进行Metropolis-in-Gibbs抽样和运行时间分析
  12. WEB应用程序--概述
  13. 人工合成生命的最新进展比AI还快
  14. 创建个人网页,创建个人网址。
  15. SQLI DUMB SERIES-10
  16. ftp服务器连接时间太长(耗时20s或40s)问题解决(超详细图文教程)
  17. vim和emac体验
  18. pacemaker+corosync 搭建一主两从PG集群
  19. Windows美化磁盘图标
  20. 鸿蒙源码导读-01:蓝海与红海

热门文章

  1. java运算符使用总结_Java运算符知识点总结
  2. html基本结构(头部需加上样式表),HTML基本结构、头部、注释(示例代码)
  3. php期末考试题机考_phP基础知识期末考试题
  4. mysql5.7 至少需要1560,mysq5.7.28配置innodb_page_size错误引起的错误1071(42000)
  5. 生成 oracle 连接串,Generator连接Oracle数据库生成Model报错
  6. 无法登陆到你的账号 桌面的文件都消失_都别拦着我,我要删库了
  7. matlab 三维绘图 抛光,瓷砖抛光过程建模与仿真
  8. java后端参数默认值添加枚举_利用自定义Validator和枚举类来限定接口的入参
  9. 华硕z170a如何开启m2_跑得快也要站得稳,华硕灵珑II笔记本保护你的数据安全
  10. java静态初始化块无法直接调用,关于JAVA静态初始化块,初始化块,构造器调用顺序的有关问题...