上一篇:Set接口 | 带你学《Java语言高级特性》之一百零四
【本节目标】
本节需要掌握分析TreeSet子类排序操作和重复元素消除的过程。
TreeSet子类排序操作
经过分析后发现,TreeSet子类中保存的数据是允许排序的,但是这个类必须要实现Comparable接口,只有实现了此接口才能够确认出对象的大小关系。
提示:TreeSet本质上是利用TreeMap子类实现的集合数据的存储,而TreeMap(树)就需要根据Comparable来确定对象的大小关系。
那么下面就使用一个自定义的类来实现排序的处理操作。
范例:使用自定义的类实现排序的处理操作
import java.util.Set;
import java.util.TreeSet;
public class JavaAPIDemo {
public static void main(String[] args) throws Exception {
Set<Person> all=new TreeSet<Person>();
all.add(new Person("张三",19));
all.add(new Person("李四",19)); //年龄相同,但姓名不同
all.add(new Person("王五",20)); //数据重复
all.add(new Person("王五",20)); //数据重复
all.add(new Person("小强",78));
all.forEach(System.out::println);
}
}
class Person implements Comparable<Person>{ //比较器
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String toString() {
return "姓名:" + this.name + "、年龄:" + this.age;
}
@Override
public int compareTo(Person per) {
if(this.age < per.age){
return -1 ;
}else if(this.age > per.age) {
return 1;
}else {
return this.name.compareTo(per.name);
}
}
}
/**
* 姓名:张三、年龄:19
* 姓名:李四、年龄:19
* 姓名:王五、年龄:20
* 姓名:小强、年龄:78
*/
在使用自定义类对象进行比较处理的时候,一定要将该类中所有属性都依次进行大小关系的匹配,否则某一个或者几个属性相同的时候也会被认为是重复数据,所以TreeSet是利用了Comparable接口来确认重复数据的。
由于TreeSet在操作过程之中需要将类中的所有属性进行比对,这样的实现难度太高了,那么在实际的开发中应该首选HashSet子类进行存储。
重复元素消除
TreeSet类是利用了Comparable接口来实现了重复元素的判断,但是Set集合的整体特征就是不允许保存重复元素。但是HashSet判断重复元素的方式并不是利用Comparable接口完成的,它利用的是Object类中提供的方法实现的:
- 对象编码:
public int hashCode();
- 对象比较:
public boolean equals(Object obj);
在进行重复元素判断的时候首先利用hashCode()进行编码的匹配,如果该编码不存在,则表示数据不存在,证明没有重复,如果该编码存在,则进一步进行对象比较处理,如果发现重复了,则此数据是不允许保存的。如果使用的是Eclipse开发工具,则可以帮助开发者自动创建HashCode()与equals()方法。
范例:实现重复元素处理
import java.util.Set;
import java.util.HashSet;
public class JavaAPIDemo {
public static void main(String[] args) throws Exception {
Set<Person> all=new TreeSet<Person>();
all.add(new Person("张三",19));
all.add(new Person("李四",19)); //年龄相同,但姓名不同
all.add(new Person("王五",20)); //数据重复
all.add(new Person("王五",20)); //数据重复
all.add(new Person("小强",78));
all.forEach(System.out::println);
}
}
class Person implements Comparable<Person>{ //比较器
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result +age;
result = prime * result + ((name == null)? 0 : name.hashCode());
return result;
}
@Override
public 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;
}
public String toString() {
return "姓名:" + this.name + "、年龄:" + this.age;
}
@Override
public int compareTo(Person per) {
if(this.age < per.age){
return -1 ;
}else if(this.age > per.age) {
return 1;
}else {
return this.name.compareTo(per.name);
}
}
}
/**
* 姓名:小强、年龄:78
* 姓名:李四、年龄:19
* 姓名:王五、年龄:20
* 姓名:张三、年龄:19
*/
在Java程序中,真正的重复元素的判断处理利用的就是hashCode和equals()两个方法共同作用完成的,而只有在排序要求的情况下(TreeSet)才会利用Comparable接口来实现。
想学习更多的Java的课程吗?从小白到大神,从入门到精通,更多精彩不容错过!免费为您提供更多的学习资源。
本内容视频来源于阿里云大学