13.4.2 Set接口的常用子类(3)
4.关于重复元素的说明
在讲解之前,先来观察以下的代码,并观察其输出。
范例:加入重复对象
- package org.lxh.demo13.setdemo;
- import java.util.HashSet;
- import java.util.Set;
- class Person { // 定义Person类
- private String name; // 定义name属性
- private int age; // 定义age属性
- public Person(String name, int age) { // 通
过构造方法为属性赋值- this.name = name; // 为name属性赋值
- this.age = age; // 为age属性赋值
- }
- public String toString() { // 覆写toString()方法
- return "姓名:" + this.name + ";年龄:" + this.age;
- }
- }
- public class RepeatDemo01 {
- public static void main(String[] args) {
- Set<Person> allSet = new HashSet<Person>();// 实
例化Set接口对象- allSet.add(new Person("张三", 30)); // 加入元素
- allSet.add(new Person("李四", 31)); // 加入元素
- allSet.add(new Person("王五", 32)); // 加入元素
- allSet.add(new Person("王五", 32)); // 重复元素,不能加入
- allSet.add(new Person("王五", 32)); // 重复元素,不能加入
- allSet.add(new Person("赵六", 33)); // 加入元素
- allSet.add(new Person("孙七", 33)); // 年龄重复
- System.out.println(allSet); // 输出集合,调用
- toString()
- }
- }
程序运行结果:
- [姓名:王五;年龄:32, 姓名:李四;年龄:31, 姓名:王五;
年龄:32, 姓名:赵六;年龄:33, 姓名:张三;年龄:30,
姓名:孙七;年龄:33, 姓名:王五;年龄:32]
从程序的运行结果中可以发现,"王五"的内容重复了,也就是说,此时的程序并没有像Set接口规定的那样是不允许有重复元素的,而如果此时想要去掉重复元素,则必须首先进行对象是否重复的判断,而要想进行这样的判断则一个类中就必须覆写Object类中的equals()方法,才能完成对象是否相等的判断,但是只覆写equals()方法是不够的,还需要覆写hashCode()方法,此方法表示一个哈希编码,可以简单地理解为表示一个对象的编码。一般的哈希码是通过公式进行计算的,可以将类中的全部属性进行适当的计算,以求出一个不会重复的哈希码。
范例:去掉重复元素
- package org.lxh.demo13.setdemo;
- import java.util.HashSet;
- import java.util.Set;
- class Person { // 定义Person类
- private String name; // 定义name属性
- private int age; // 定义age属性
- public Person(String name, int age) { // 通过构
造方法为属性赋值- this.name = name; // 为name属性赋值
- this.age = age; // 为age属性赋值
- }
- public boolean equals(Object obj) { // 覆写equals()方法
- if (this == obj) { // 地址相等
- return true; // 是同一个对象
- }
- if (!(obj instanceof Person)) { // 传递进来
的不是本类的对象- return false; // 不是同一个对象
- }
- Person p = (Person) obj; // 进行向下转型
- if (this.name.equals(p.name) && this.age == p.age) {
- return true ; // 属性依次比较
- }else{ // 全部属性相等,
是同一对象- return false ; // 属性不相等,
不是同一对象- }
- }
- public int hashCode(){ // 覆写hashCode()方法
- return this.name.hashCode() * this.age ; // 指定编码公式
- }
- public String toString() { // 覆写toString()方法
- return "姓名:" + this.name + ";年龄:" + this.age;
- }
- }
- public class RepeatDemo02 {
- public static void main(String[] args) {
- Set<Person> allSet = new HashSet<Person>();// 实例化Set接口对象
- allSet.add(new Person("张三", 30)); // 加入元素
- allSet.add(new Person("李四", 31)); // 加入元素
- allSet.add(new Person("王五", 32)); // 加入元素
- allSet.add(new Person("王五", 32)); // 重复元素,不能加入
- allSet.add(new Person("王五", 32)); // 重复元素,不能加入
- allSet.add(new Person("赵六", 33)); // 加入元素
- allSet.add(new Person("孙七", 33)); // 年龄重复
- System.out.println(allSet); // 输出集合,调用
- toString()
- }
- }
程序运行结果:
- [姓名:王五;年龄:32, 姓名:李四;年龄:31,
姓名:张三;年龄:30, 姓名:孙七;年龄:33, 姓名:赵六;年龄:33]
从最后输出的结果中可以发现,集合中的重复内容消失了,就是因为equals和hashCode共同作用的结果。
U提示:Object类总结。
经过以上程序代码的学习,Object类中的全部方法就介绍完了,相信读者应该清楚地知道了各个方法的作用。在实际的开发中经常会碰到区分同一对象的问题,所以,一个完整的类最好覆写Object类的hashCode()、equals()、toString() 3个方法。