使用 Java HashSet 时要注意的一些地方
来源:互联网 发布:淘宝黑搜原理 编辑:程序博客网 时间:2024/05/19 04:05
HashSet<T>类主要是设计用来做高性能集运算的,例如对两个集合求交集、并集、差集等。集合中包含一组不重复出现且无特性顺序的元素。
2、HashSet<T>的容量会按需自动添加。
HashSet<T>的一些特性如下:
1、HashSet<T>中的值不能重复且没有顺序。2、HashSet<T>的容量会按需自动添加。
下面是使用 Java HashSet 时要注意的一些地方:
package com.swsx.hashCode;import java.util.HashSet;import java.util.Iterator;import java.util.Set;/** * 使用HashMap要注意的一些问题 * @author Administrator * */public class TestHashSet {public static void main(String[] args){Person p1 = new Person("张三",21);Person p2 = new Person("李四",22);Person p3 = new Person("张三",21);Set<Person> persons = new HashSet<Person>();persons.add(p1);persons.add(p2);persons.add(p3);/* * HashSet是按hashCode来存储元素的,如果两个元素的hashCode相同且equals为true,则只存一个元素, * Person的hashCode和equals方法已重写,由于p1和p3的hashCode相同且equals,所以p3没有被存入。 * 如果不重写hashCode,而只重写equals方法,则会造成HashSet存储重复的元素。 * */System.out.println("HashSet中有:" + persons.size() + "个元素:");Iterator<Person> iterator = persons.iterator();while(iterator.hasNext()){System.out.println(iterator.next());}if (persons.contains(p1)) {System.out.println("HashSet中有元素"+ p1);}else{System.out.println("HashSet中没有元素"+ p1);}/* * 当改变元素值时,hashCode也变了. */System.out.println("\np1改变前的hashCode:" + p1.hashCode());p1.setName("小武");System.out.println("p1改变后的hashCode:" + p1.hashCode() + "\n");System.out.println("HashSet中有:" + persons.size() + "个元素:");iterator = persons.iterator();while(iterator.hasNext()){System.out.println(iterator.next());}/* * HashSet是按元素的hashCode存取的,当改变元素值时,hashCode也变了, * 造成查找元素时的hashCode和存储时的hashCode不一致,结果就找不到元素了。 * 当我们遍历集合时,要查找的元素确实存在,只不过仍是按原来元素的hashCode存储的, * 但查找时却是按新的hashCode来找的。 */if (persons.contains(p1)) {System.out.println("HashSet中有元素"+ p1);}else{System.out.println("HashSet中没有元素"+ p1);}/* * 改回原来的元素值时,hashCode也改回来了,这时查找时的hashCode和 * 存储时的hashCode一致,元素就找到了了。 */p1.setName("张三");System.out.println("\np1改回来后的hashCode:" + p1.hashCode());System.out.println("HashSet中有:" + persons.size() + "个元素:");iterator = persons.iterator();while(iterator.hasNext()){System.out.println(iterator.next());}if (persons.contains(p1)) {System.out.println("HashSet中有元素"+ p1);}else{System.out.println("HashSet中没有元素"+ p1);}}}/** * 用于测试HashSet的类 * @author Administrator * */class Person{private String name; private int age;public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}/** * 重写父类hashCode方法(hash算法不唯一) */@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + age;result = prime * result + ((name == null) ? 0 : name.hashCode());return result;}/** * 重写父类的equals方法 */@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;Person other = (Person) obj;if (age != other.age)return false;if (name == null) {if (other.name != null)return false;} else if (!name.equals(other.name))return false;return true;}@Overridepublic String toString() {return "Person [name=" + name + ", age=" + age + "]";}}/*输出如下:HashSet中有:2个元素:Person [name=张三, age=21]Person [name=李四, age=22]HashSet中有元素Person [name=张三, age=21]p1改变前的hashCode:776501p1改变后的hashCode:759683HashSet中有:2个元素:Person [name=小武, age=21]Person [name=李四, age=22]HashSet中没有元素Person [name=小武, age=21]p1改回来后的hashCode:776501HashSet中有:2个元素:Person [name=张三, age=21]Person [name=李四, age=22]HashSet中有元素Person [name=张三, age=21]*/
总结:
1.如果一个类重写的equals方法,那么也最好重写hashCode方法,尤其是要使用与hash算法有关的集合(如HashSet、HashMap)存储对象时,这是最佳实践。
2.当一个对象被存储进HashSet集合中以后,就不能修改这个对象中的那些参与计算哈希值的字段了,否则,对象修改后的哈希值与最初存储进HashSet集合中时的哈希值就不同了,在这种情况下,即使在contains方法中使用该对象的当前引用作为的参数去HashSet集合中检索对象,也将返回找不到对象的结果,这也会导致无法从HashSet集合中单独删除当前对象,从而造成内存泄漏。
0 0
- 使用 Java HashSet 时要注意的一些地方
- 从头认识java-15.3 使用HashSet需要注意的地方
- 关于Android PopupWindow 使用要注意的一些地方
- 一些java注意的地方,应付用
- Java中的一些需要注意的地方
- java HashMap需要注意的一些地方
- Vector使用时要注意的地方
- 使用NSNotificationCenter时要注意的地方
- selenium的一些要注意的地方
- 关于scanf输入数据时要注意的一些地方
- 引用 && const 要注意的一些地方
- 在java中使用常量变量的一些需要注意的地方
- Java注意的地方
- Java注意的地方
- 一些值得注意的地方
- 一些需要注意的地方
- C++一些注意的地方
- cuda一些注意的地方
- Eclipse快捷键 10个最有用的快捷键
- 【Android解决方案】连接SQL Server
- php 玩QQ客服加群等,你会了吗?
- VTK中的vtkPlaneWidget显示在QT的qvtkwidget中
- 基于Telit GL868 初步调试总结
- 使用 Java HashSet 时要注意的一些地方
- 解决 虚拟机VirtualBox安装ubuntu 12.04LTS x32 The system is running in low-graphics mode问题
- Android通过webservice连接SQLServer 详细教程(数据库+服务器+客户端)
- 我爱你,亲爱的。
- 随机数——Linux C编程
- Demo
- 黑马程序员---银行业务控制系统
- 链队列
- 随机数 权重 概率