-- hashCode():
把对象的所有成员变量值相加即可。如果是基本类型,就加值。如果是引用类型,就加哈希值。
public int hashCode()
{
return this.name.hashCode() + this.age*13 + this.sex*17 +this.score*21;
}
--equals():
A:this==obj
B:!(obj instanceof Student)
C:所有成员变量的值比较。基本类型用==,引用类型用equals()。
④. 如果不会,eclipse()自动生成。
package testdemo;
import java.util.HashSet;
public class HashSetDemo2 {
public static void main(String[] args) {
// 创建集合对象
HashSet<Student> hs = new HashSet<Student>();
// 创建元素对象
Student s1 = new Student("林青霞", 26);
Student s2 = new Student("张曼玉", 36);
Student s3 = new Student("周慧敏", 20);
Student s4 = new Student("林青霞", 26);
Student s5 = new Student("林青霞", 66);
Student s6 = new Student("林志玲", 16);
// 添加元素
hs.add(s1);
hs.add(s2);
hs.add(s3);
hs.add(s4);
hs.add(s5);
hs.add(s6);
// 遍历
for (Student s : hs) {
System.out.println(s.getName() + "***" + s.getAge());
}
}
}
--创建创建自定义类Student:
package testdemo;
public class Student {
private String name;
private int age;
public Student() {
}
public Student(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;
}
@Override
//重写hashCode()方法.
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
//重写equals()方法
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) 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;
}
}
3.TreeSet
a、底层结构是二叉树。按照树节点进行存储和取出。
b、根据构造方法的不同,选择使用 自然排序 或者 比较器排序。按照实际的需求,可以对元素进行排
序。并且保证唯一。
c、原理:二叉树保证元素唯一 排序
①:第一个添加的数据作为根节点。
②:从第二个开始,每一个数据从根节点开始比较,如果大了,往右边放, 如果小了,往左边
放, 如果相同,替换。
③:原理图如下:
(2). 两种实现方式:
①、自然排序:(元素具备比较性)-------对象所属类实现comparable接口重写了接口中的比较方法,
而具有了比 较的功能,进而有了 "排序" 的功能。通过 TreeSet的无参构造,要求对象所属的
类实现 Comparable接口,重写comparable中的comparTo方法,定义自己的比较方法。
#重写compareTo()方法:
#this.是将要判断存入的元素,s已经在集合中存在的元素 [负数往前方,整数往s的后面放,0不存放]
#由于对象有多个成员变量,你不能根据其中的某一个决定其他的。
#因此 当某一个主要参数相同的时候,你还需要判断其他的是不是也是相同的。
public int compareTo( Studetn s )
{
// 需求:比较年龄
int num = this.age - s.age ;
//次要条件 :
int num2 = ( num == 0 ) ? ( this.name.compareTo( s.name ) ) : num ;
return num2;
}
②、比较器排序:(集合具备比较性)----通过构造方法,传入构造器(实现了comparable接口的对象),
而具有了比较的功能,进而具备了排序的功能
#TreeSet的带参构造,要求构造方法接收一个实现了Comparator接口的对象。如下:
TreeSet<Student> ts = new TreeSet<Student> ( new Comparator<Student>
{
public int compare ( Student s1 , Student s2)
//其中s1是将要判断存入的元素,s2已经在集合中存在的元素[负数往前方,
整数往s2的后面放,0不存放]
{
//按照年龄排序,从小到大
int num = s1.getAge() - s2.getAge();
//次要条件
int num2 = ( num == 0 ) ? ( s1.getName().compareTo(s2.getName()) ) : num;
return num2;
}
} );
(3). 案例:TreeSet存储自定义对象按照姓名长度排序:
①、自然排序:(元素具备比较性)-------对象所属类实现comparable接口重写compareTo()
A:创建TreeSetDemo类:
package testdemo;
import java.util.TreeSet;
public class TreeSetDemo{
public static void main(String[] args) {
// 创建TreeSet集合 ts.
TreeSet<Student> ts = new TreeSet<Student>();
// 创建并添加元素
ts.add(new Student("刘德华", 52));
ts.add(new Student("成龙", 60));
ts.add(new Student("周星驰", 44));
ts.add(new Student("孙燕姿", 34));
ts.add(new Student("林青霞", 26));
ts.add(new Student("林青霞", 36));
ts.add(new Student("林青", 26));
ts.add(new Student("林青霞", 26));
// 遍历
for (Student s : ts) {
System.out.println(s.getName() + "***" + s.getAge());
}
}
}
B:创建
Student
类:
package testdemo;
public class Student implements Comparable<Student> {
private String name;
private int age;
public Student() {
}
public Student(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;
}
@Override
public int compareTo(Student s) {
// 姓名的长度
int num = this.name.length() - s.name.length();
// 很多时候,别人给我们的需求其实只是一个主要需要
// 还有很多的次要需求是需要我们自己进行分析的。
// 比较姓名的内容
int num2 = (num == 0) ? (this.name.compareTo(s.name)) : num;
// 继续分析,姓名长度和内容都相同的情况下,年龄还可能不一样呢?
// 所以,当姓名长度和内容都相同的时候,我们在比较下年龄就好了
int num3 = (num2 == 0) ? (this.age - s.age) : num2;
return num3;
}
}
C:运行结果如下
:
②、比较器排序:(集合具备比较性)----通过构造方法,传入构造器(实现了comparable接口的对象)
A:创建TreeSetDemo类:
package testdemo;
import java.util.Comparator;
import java.util.TreeSet;
/*
* 比较器接口 Comparator。带参构造。
*/
public class TreeSetDemo {
public static void main(String[] args) {
// 匿名内部类
TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {
public int compare(Student s1, Student s2) {
// 按年龄排序,从小到大
int num = s1.getAge() - s2.getAge();
// 次要条件
int num2 = (num == 0) ? (s1.getName().compareTo(s2.getName())) : num;
return num2;
}
});
// 创建并添加元素对象
ts.add(new Student("刘德华", 52));
ts.add(new Student("成龙", 60));
ts.add(new Student("周星驰", 44));
ts.add(new Student("孙燕姿", 34));
ts.add(new Student("林青霞", 26));
ts.add(new Student("林青霞", 36));
ts.add(new Student("林青", 26));
ts.add(new Student("林青霞", 26));
// 遍历
for (Student s : ts) {
System.out.println(s.getName() + "***" + s.getAge());
}
}
}
B:创建
Student
类:
package testdemo;
public class Student{
private String name;
private int age;
public Student() {
}
public Student(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;
}
}
C:运行结果如下
: