这个是我做项目过程中遇到的的一个问题,当时的需求是要求对使用excel导入的数据做判重校验(所有列的数据都一样判定为重复数据),如果里面有输入重复的数据的话,就记录哪些行是重复的数据,记录对应的行号,返回给前端显示给用户
最开始的想法是把所有excel里面的数据全部读出来,放在一个map中,map的key记录行号,value保存数据行转化之后的对象,然后通过遍历map集合,一个个的去比较。
这种方式肯定是可行的,但是当时觉得太麻烦了,并且效率很低,就没有用这种方式去做,当时在想有没有更简单的,更高效的方式来实现呢?
后面问了下同事,然后结合网上查阅的资料,找到了一种比较好的方式来实现,这里记录下,防止遗忘,也希望可以帮到遇到这个问题的朋友们。
简单说下具体的思路:
- 准备一个list集合,用于存放每一行的数据
- 准备一个pojo实体类,在类上加上lombok的@Data注解
- for循环读取excel每一行的数据,并用一个对象保存起来
- 调用list的contains方法,如果返回为true则存在重复数据
- 记录重复行行号,也就是for循环里面的循环变量
- 将对象添加到list中
其中有几个很关键的步骤:
步骤2中在类上加上@Data注解的意义是为了重写该类的equals和hashcode方法,为后面list调用contain比较做铺垫,contains方法底层还是通过调用类的equals方法来实现的,可以看下这篇文章:
关于lombok的@Data注解在此场景的应用可以看下这个
为什么要重写equals方法?重写是为了能实现两个对象的比较,我们校验数据行是否重复,本质上就是比较两个对象里面的内容是否一样,如果不重写的话,那么比较的是两个对象在内存中的存放地址,这样即使他们里面的数据一样,最后比较的结果也会不一样。
步骤4和步骤6的顺序很重要,一定是要先调list的contains方法,然后在将对象添加到list集合中,具体为什么,大家自己想一下应该都能明白吧。
看了我啰嗦这么多,可能有些人会有点迷糊,可以看一下我写的伪代码
@Data
public class obj {
属性·······
属性·······
属性·······
属性·······
属性·······
属性·······
}
list<obj> contentList =new arrayList<>();//保存excel每一行的数据
list<String> errorMsg=new arrayList<>();//保存错误信息
for (int i = 1; i <= rowNum; i++) {
obj rowDataObj = new obj();
if (contentList.contains(rowDataObj)){
errorMsg.add("第"+(i+1)+"行数据在文件中已存在")
}
contentList.add(rowDataObj)
}
好了就这样吧,拜了个拜le。