一、HashSet
1.1 HashCode值
概念: Hashcode值是根据内存地址生成的一个十进制整数,不能使用hashcode值来表示对象的地址值;
获取hashcode值的方法:
public int hashcode()//返回对象的哈希码值
注意:
- 不能根据hashcode的值来判断两个对象是否同一个对象,自定义对象以及引用数据类型,一般都会重写hashcode值方法;
- 字符串重写了hashcode方法,字符串内容一样,hashcode也是一样;
- 字符串可能出现hash冲突,字符串内容会不同,但hashcode值相同;
1.2 HashSet的特点
- 此类实现Set接口;
- 以hash表结构存储;
- 在多线程中不安全;
- 底层HashMap实例的默认初始容量是16;
案例
/*需求:存入三个学生对象(name,age)到HashSet集合,
如果对象的属性值完全相同,则不存入到集合,其余都存入*/
package demon03;
import java.util.Objects;
//学生类
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
public boolean equals(Object obj) {
if (this == obj)
return true;
//getClass返回Class类型对象
if (obj == null || getClass()!=obj.getClass())
return false;
//多态 向下转型
Student student = (Student)obj;
return age==student.age&& Objects.equals(name,student.name);
}
@Override
public int hashCode() {
return Objects.hash(name,age);
}
@Override
public String toString() {
return "Student{"+"name="+name+'\''+",age="+age+'}';
}
}
package demon03;
import java.util.HashSet;
import java.util.Set;
//测试类
public class Test {
public static void main(String[] args) {
//实例化集合
Set set = new HashSet();
//实例化对象
Student stu01 = new Student("Tom",18);
System.out.println(stu01.hashCode());
Student stu02 = new Student("Joey",19);
Student stu03 = new Student("Lili",25);
System.out.println(stu03.hashCode());
//将对象存入集合中
set.add(stu01);
set.add(stu02);
set.add(stu03);
System.out.println(set);
}
}
二、TreeSet
2.1 特点
- 基于TreeSet的NavigableSet实现;
- 对元素进行自然排序;
- Comparable 或Comparator设置排序规制;
- 此实现不是同步的,在多线程中也是不安全的;
2.2 排序的规制
- 数值类型的数据按照升序(从小到大)进行排序;
- 对字符串类型的数据,按照字符串的首字母ascall码表来进行排序;
- 对于自定义类的引用数据类型,如果不指定排序的规制,添加到集合中会报错;
2.3 引用数据类型排序规制
- 定义类中实现接口Comparable:
-this>object ===>正数 表示按照升序排序;
-this=object ===>等于0 表示是相同的元素(不会存入到集合);
-this<object ===>负数 表示按照降序排序; - 实例化集合的时候传递比较的规制;
案例:
package demon04;
//学生类
public class Student implements Comparable {
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(Object o) {
Student stu =(Student)o;
if (this.getAge()==stu.getAge()){
return this.getName().charAt(0)-stu.getName().charAt(0);
}
return this.getAge()-stu.getAge();
}
}
//测试类-01
package demon04;
import java.util.TreeSet;
public class Test01 {
public static void main(String[] args) {
//添加数据到集合set中
//数值类型
TreeSet set01 = new TreeSet();
set01.add(1);
set01.add(100);
set01.add(80);
set01.add(40);
set01.add(60);
System.out.println(set01);
//对于字符串类型
TreeSet set02 = new TreeSet();
set02.add("ab");
set02.add("cfg");
set02.add("bcd");
set02.add("dkf");
set02.add("zwh");
set02.add("张三");
System.out.println(set02);
//自定义引用数据类型
TreeSet set03 = new TreeSet();
//将数据添加集合中
set03.add(new Student("张无忌",25));
set03.add(new Student("三毛",20));
set03.add(new Student("金毛狮",18));
System.out.println(set03);
}
}
运行结果:
package demon04;
//测试类-02
import java.util.Comparator;
import java.util.TreeSet;
public class Test02 {
public static void main(String[] args) {
TreeSet set = new TreeSet(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
//多态向下转型
Student stu01 = (Student)o1;
Student stu02 = (Student)o2;
return stu01.getAge()- stu02.getAge();
}
});
set.add(new Student("张三",20));
set.add(new Student("李四",19));
set.add(new Student("王五",42));
System.out.println(set);
}
}
运行结果: