- 浏览: 39173 次
- 性别:
- 来自: 台州
最新评论
今天按照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 2294有些登陆需要涉及到重定向登录虾米音乐网的例子httpcli ... -
poi:无法获取公式值
2012-06-01 09:16 2212有时候用cell.getNumericCellValue()无 ... -
compress 解压缩
2012-03-13 17:02 2125主要用到了apach commons里 ... -
apache ant 解压缩zip
2012-03-08 15:39 1855使用apache ant.tools.zip来打包和解压缩。 ... -
改变ie查看源代码的打开方式
2012-02-22 09:47 1426更改IE的“查看源代码”打开的编辑器--notepa ... -
又简单又好用的同步控制
2012-02-21 10:45 799上代码 package com.enfang; /** ... -
struts2接收前台参数的3个方法
2012-02-10 09:18 388201.public class GetRequestParam ... -
DBCP的使用
2012-01-31 10:40 1031反正是工具类,直接上代码吧。复制一下就可以用了 pac ... -
邮件抓取器的实现
2012-01-19 14:16 911朋友要一个邮件抓取器 ... -
java map的遍历
2012-01-19 11:36 776有时候需要对map进行排序,什么会进行对map的遍历,以下是对 ... -
JOptionPane JOptionPane
2012-01-16 14:35 940package T1; import jav ... -
httpClient的使用
2012-01-13 13:42 907httpClient的简单使用方法(代理方式的)。 p ... -
FileUpload
2012-01-11 15:49 791以下为apache fileupload的使用。 先一个se ... -
poi :合并excel的单元格
2011-12-19 15:32 1228// 合并单元格 从左上角合并到右下角 ... -
HtmlPaser与StringEscapeUtils共舞抓取网页
2011-12-13 14:48 1517用正则来匹配的确很强大,但如果是网页的话HtmlPaser更方 ... -
jacob:no jacob-1.15-M4-x86 in java.library.path
2011-12-13 13:37 2645今天遇到一个很蛋疼的问题,生成ppt的时候老抱no jacob ...
相关推荐
### Java 计算同一 List 中是否有相同值 在 Java 编程中,判断一个 `List` 中是否存在重复元素是一项常见的需求。特别是在数据处理、验证或分析等场景中,确保数据的唯一性对于维持数据完整性至关重要。 #### 核心...
现在,`my_unique_list`包含了`[1, 2, 3, 4]`,并且元素顺序与原始List相同。 另外,Python的列表推导式也可以用来过滤掉重复的元素,但这仅适用于Python 3.7及以上版本,因为之前版本的列表不保证插入顺序: ```...
这种方法的基本思想是通过双重循环来遍历列表中的每个元素,并检查是否存在相同的元素。如果存在,则移除重复项。 ```java for (int i = 0; i < list.size(); i++) { for (int j = i + 1; j < list.size(); j++) {...
比较两个列表是否相等,可以使用`List<T>.SequenceEqual()`方法,它会检查两个列表的顺序和元素是否都相同: ```csharp List<string> compareList = new List(stringList); bool areEqual = stringList....
- `remove(Object key)`:移除与指定键相关联的映射项。 #### 1.4.3 Comparable接口 Map中的键通常需要实现Comparable接口,以便于排序。当Map使用有序键(比如TreeMap)时,键对象之间的比较顺序决定了Map中的...
列表可以包含任何X++类型的成员,但同一列表中的所有成员必须是相同类型。List的常用方法有: - `addEnd()` - 在列表末尾添加一个成员。 - `addStart()` - 在列表开头添加一个成员。 - `elements()` - 返回列表中...
multimap允许多个键相同的元素存在,因此`begin()`函数在遍历时可能返回具有相同键的不同元素。 ### begin(multiset) `begin(multiset)`函数是multiset容器的成员函数,用于返回指向multiset容器中第一个元素的...
Java集合框架主要由以下几种类型的接口构成:`Collection`、`Set`、`List`、`Queue`、`Deque`以及`Map`。其中,`Collection`是最基本的接口,其他几种集合类如`Set`、`List`、`Queue`等都是它的子接口。 - **`...
- **数组**:最简单的数据结构之一,能够存储相同类型的多个数据项。 - **栈**:遵循后进先出(LIFO)原则的数据结构。 - **链表**:由一系列节点组成,每个节点包含数据和指向下一个节点的指针。 - **哈希表**:利用...
在Java编程中,解决有向图(Directed Graph)中的环路问题是一项常见的任务。有向图是由节点(或顶点)和边组成的图,其中边具有方向性,即从一个节点指向另一个节点。环路是指在图中存在一条路径,起点和终点相同,...
向`HashSet`中插入第二个`Person`对象将导致第一个`Person`对象作为重复项被移除。 D. 确定`HashSet`中是否包含某个`Person`对象的时间是常数,并且不依赖于地图的大小。 **正确答案**:A **解析**: - **选项A**...
5. **源码分析**:源码中可能会使用到`比较`和`等于`操作来检测两个元素是否相同,同时可能利用`删除`或`替换`操作移除或修改重复的元素。此外,可能还会有错误处理机制,确保程序在遇到重复元素时不会中断。 6. **...
3. **List**: List由双向链表组成,允许在任意位置高效地插入和删除元素,但访问元素需要遍历链表,速度较慢。由于元素之间的内存不连续,不适合随机访问。 4. **Queue**: Queue是一种先进先出(FIFO,First In ...
在某些较低版本中,可以使用`rabbitmqctl cluster {rabbit_node_name}`命令来达到相同效果。 **启动应用程序:** - `rabbitmqctl start_app`:重新启动已经通过`stop_app`命令停止的应用程序。 **检查集群状态:**...
// 去除后面的相同项 j--; // 调整索引 } } } return list; } let arr = [1, 1, 'a', 'a', true, true, false, false, null, '', null, '', undefined, undefined]; distinct2(arr); // [1, "a", true, false,...
当前指针元素与后指针元素相同时,将后指针元素移除,直到前指针到达数组末尾。这种方法需要保持原始顺序,但效率较低,时间复杂度为O(n^2)。 在易语言中实现这些方法时,需要注意的是,由于易语言的特性,可能需要...
其中,Map接口不同于Set和List,因为它不存储重复元素,而是通过键来唯一标识每个值。HashMap就是实现Map接口的一个具体类,允许null键和null值,并且提供了快速的插入、删除和查找操作。 HashMap的工作原理基于...
需要注意的是,通过这种方式转换得到的`List`集合是数组的视图,对`List`的修改会影响到原始数组。 以上就是关于“Tedu一段Java集合Collection”的详细知识点介绍,包括集合的基本概念、集合框架、`Collection`接口...
购物车类还需要实现计算总价的方法,这可以通过遍历商品项并累加每个商品的总价格(数量乘以单价)来完成。此外,可能还需要提供根据商品ID删除或更新商品数量的功能。 接下来,我们需要考虑如何与数据库或服务进行...
在Cisco网络设备中,端口限速是一项重要的流量管理技术,它能够帮助管理员有效地控制通过特定接口的数据流量,防止网络拥塞并确保关键业务的正常运行。下面我们将详细介绍如何在Cisco路由器上配置端口限速。 ##### ...