- 浏览: 37879 次
- 性别:
- 来自: 台州
最新评论
通过set移除list相同项
- 博客分类:
- JAVA
今天按照boss的要求做的时候,遇到了一个问题。boss一条记录里只要A,B,C三个条件相等的时候,这条记录也就相等,删掉重复的两条,保留一条。于是心想,数据量比较大,只取一次数据,然后在对这些数据进行处理后,用到不同的输出里,应该问题不大,既然是实体类,那么就重写一下equals方法,然后用set去装原来的list就成了。文字表达不好,下面就举例子吧。
比如如下实体类:
public class T { String name; Date sDate; Date eDate; String age; public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getsDate() { return sDate; } public void setsDate(Date sDate) { this.sDate = sDate; } public Date geteDate() { return eDate; } public void seteDate(Date eDate) { this.eDate = eDate; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } @Override public boolean equals(Object obj) { if((this.age).equals(obj.toString())){ return true; } return false; } @Override public String toString() { return this.age; } }
重写了equals和tostring方法,以为成功大吉了。
于是测了一把(代码如下):
class tt{ public static void main(String[] args) throws Exception { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S"); T t1 = new T(); t1.setAge("1"); t1.setsDate(sdf.parse("2012-02-01 02:02:02.0")); t1.setName("a"); T t2 = new T(); t2.setAge("1"); t2.setsDate(sdf.parse("2012-02-01 02:02:02.0")); t2.setName("b"); boolean b12 = t1.equals(t2); T t3 = new T(); t3.setAge("1"); t3.setsDate(sdf.parse("2012-02-01 02:02:02.0")); t3.setName("c"); T t4 = new T(); t4.setAge("2"); t4.setsDate(sdf.parse("2012-02-01 02:01:02.0")); t4.setName("d"); boolean b34 = t3.equals(t4); T t5 = new T(); t5.setAge("2"); t5.setsDate(sdf.parse("2012-02-01 02:01:02.0")); t5.setName("e"); List<T> list = new ArrayList<T>(); list.add(t1); list.add(t2); list.add(t3); list.add(t4); list.add(t5); Set<T> set = new HashSet<T>(); for(T t:list){ System.out.println(set.add(t)); } System.out.println(set.size()); } }
输出:
true
true
true
true
true
5
当时就郁闷了,set咋就全部把记录都插进去了呢。
当时还不信了,又写了一个玩样来测试。
public class T1 { public static void main(String[] args) { T1 t = new T1(); t.test(); } public void test(){ String str1 = "1"; String str2 = "1"; String str3 = "2"; String str4 = "2"; String str5 = "1"; List list = new ArrayList(); list.add(str1); list.add(str2); list.add(str3); list.add(str4); list.add(str5); HashSet set = new HashSet(list); System.out.println(set.size()); } }
输出:2
这又正确的。
查阅了网上资料发现:
原来set的不重复是这样实现的:
第一步1.计算即将放进去的对象的hashcode,如果计算出的这个位置里没有对象,set就认为这对象并不存在,于是直接加进去了。注意!是直接加进去了,不管equals了。
第二部2.如果在1中计算出的hashcode的位置中有一个对象了,那么set会去找equals方法了,此时如果equals返回true就不加了,返回false,再进行一次散列,将该对象放到散列后计算出的新地址里,于是就加进去了。
总结一下:在java集合中,判断两个项相等是这样的:
附件图片(其实就是上面的第一步和第二步不看也罢)
于是重写了equals,必须重写hashcode,因为string是重写过这两个方法,因此刚才第二个测试set没有把相同的加进去,而我们有时候写的实体类没重写hashcode,new一个对象的时候,hashcode不同,那么set就全部都可以加进去了。
于是重写改写了上面的方法:
public class T { String name; Date sDate; Date eDate; String age; public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getsDate() { return sDate; } public void setsDate(Date sDate) { this.sDate = sDate; } public Date geteDate() { return eDate; } public void seteDate(Date eDate) { this.eDate = eDate; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } @Override public boolean equals(Object obj) { if((this.age).equals(obj.toString())){ return true; } return false; } @Override public String toString() { return this.age; } @Override public int hashCode() { return Integer.parseInt(this.age); } } class tt{ public static void main(String[] args) throws Exception { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S"); T t1 = new T(); t1.setAge("1"); t1.setsDate(sdf.parse("2012-02-01 02:02:02.0")); t1.setName("a"); T t2 = new T(); t2.setAge("1"); t2.setsDate(sdf.parse("2012-02-01 02:02:02.0")); t2.setName("b"); boolean b12 = t1.equals(t2); T t3 = new T(); t3.setAge("1"); t3.setsDate(sdf.parse("2012-02-01 02:02:02.0")); t3.setName("c"); T t4 = new T(); t4.setAge("2"); t4.setsDate(sdf.parse("2012-02-01 02:01:02.0")); t4.setName("d"); boolean b34 = t3.equals(t4); T t5 = new T(); t5.setAge("2"); t5.setsDate(sdf.parse("2012-02-01 02:01:02.0")); t5.setName("e"); List<T> list = new ArrayList<T>(); list.add(t1); list.add(t2); list.add(t3); list.add(t4); list.add(t5); Set<T> set = new HashSet<T>(); for(T t:list){ System.out.println(set.add(t)); } System.out.println(set.size()); } }
多写了一个hashcode()
运行一下 输出:
true
false
false
true
false
2
@Override public int hashCode() { return 1; }
发表评论
-
httpclient重定向和post
2012-07-10 15:55 2239有些登陆需要涉及到重定向登录虾米音乐网的例子httpcli ... -
poi:无法获取公式值
2012-06-01 09:16 2158有时候用cell.getNumericCellValue()无 ... -
compress 解压缩
2012-03-13 17:02 2075主要用到了apach commons里 ... -
apache ant 解压缩zip
2012-03-08 15:39 1804使用apache ant.tools.zip来打包和解压缩。 ... -
改变ie查看源代码的打开方式
2012-02-22 09:47 1379更改IE的“查看源代码”打开的编辑器--notepa ... -
又简单又好用的同步控制
2012-02-21 10:45 747上代码 package com.enfang; /** ... -
struts2接收前台参数的3个方法
2012-02-10 09:18 383101.public class GetRequestParam ... -
DBCP的使用
2012-01-31 10:40 994反正是工具类,直接上代码吧。复制一下就可以用了 pac ... -
邮件抓取器的实现
2012-01-19 14:16 861朋友要一个邮件抓取器 ... -
java map的遍历
2012-01-19 11:36 730有时候需要对map进行排序,什么会进行对map的遍历,以下是对 ... -
JOptionPane JOptionPane
2012-01-16 14:35 894package T1; import jav ... -
httpClient的使用
2012-01-13 13:42 854httpClient的简单使用方法(代理方式的)。 p ... -
FileUpload
2012-01-11 15:49 750以下为apache fileupload的使用。 先一个se ... -
poi :合并excel的单元格
2011-12-19 15:32 1131// 合并单元格 从左上角合并到右下角 ... -
HtmlPaser与StringEscapeUtils共舞抓取网页
2011-12-13 14:48 1472用正则来匹配的确很强大,但如果是网页的话HtmlPaser更方 ... -
jacob:no jacob-1.15-M4-x86 in java.library.path
2011-12-13 13:37 2606今天遇到一个很蛋疼的问题,生成ppt的时候老抱no jacob ...
相关推荐
javascript array list into setjavascript array list into setjavascript array list into setjavascript array list into setjavascript array list into setjavascript array list into setjavascript array ...
如果有相同键对象,最后一次加入的键对象和值对象将会覆盖以前的; Eg: package test; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.TreeMap; public class NewMap...
Java相关 public static void main(String[] args) { User u1=new User(1, "zhangsan"); User u2=new User(2, ... Set userset=new HashSet(); userset.add(u1); userset.add(u2); userset.add(u3);
// java中对象容器主要有Set,List和Map三个接口类。 // 迭代器(Iterator)模式,又叫做游标(Cursor)模式。 // GOF给出的定义为:提供一种方法访问一个容器(container)对象中的各个元素, // 而又不需暴露该...
List– 对象之间有指定的顺序,允许重复元素,并引入位置下标。 Map – 接口用于保存关键字(Key)和数值(Value)的集合,集合中的每个对象加入时都提供数值和关键字。Map 接口既不继承 Set 也不继承 ...
List和Set分别使用retainAll方法效率比较,Set.retainAll方法效率较高
该资源通过实例说明Set、迭代器、list用法,以及Set与List的区别。
set,list,map区别与联系,很详细的介绍了区别和联系
DataStruct_SetList.rar DataStruct_SetList.rar DataStruct_SetList.rar DataStruct_SetList.rar DataStruct_SetList.rar DataStruct_SetList.rar
List,set,Map 的用法和区别 List,set,Map 的用法和区别
Java应用:两种Java容器类List和Set分析
list map set联系与区别 list map set联系与区别 list map set联系与区别
java集合类list-set-map.doc
Java集合Collection、List、Set、Map使用详解
详细描述map、list、set的常用子类特性,各个场景的适用。
以下是一些python的list和set的基本操作 1. list的一些操作 list = [1, 2, 3] list.append(5) print(list) list.extend([7, 8]) # extend是将可迭代对象的元素依次加入列表 print(list) list.append([7, 8]) # ...
SetList.cpp
java中list、set和map 的区别
java List、Set与Array之间的相互转换 java List、Set与Array之间的相互转换
测试报告与总结\list,set,map,数组间的相互转换.rar测试报告与总结\list,set,map,数组间的相互转换.rar测试报告与总结\list,set,map,数组间的相互转换.rar测试报告与总结\list,set,map,数组间的相互转换.rar