Set接口 [Collection】的子类
HashSet
特点【无序,不可重复,不能排序】
默认比较地址值【地址相同的值相同】,重写后可比较内容【内容相同的值相同】
1.比较地址值【默认】
public class Demo1 {public static void main(String[] args) {HashSet<Student> hs = new HashSet<>();Student s1 = new Student("张三", 18);Student s2 = new Student("李四", 18);Student s3 = new Student("张三", 18);System.out.println("s1:"+ s1.hashCode());System.out.println("s2:"+ s2.hashCode());System.out.println("s3:"+ s3.hashCode());System.out.println("s1:"+ s1.hashCode());hs.add(s1);hs.add(s2);hs.add(s3);for(Student student : hs){System.out.println(student);}}
}打印结果:
--------------------------------------------------------------
s1:189568618
s2:960604060
s3:1349393271
s1:189568618
Student{name='张三', age=18}
Student{name='张三', age=18}
Student{name='李四', age=18}
2.而默认比较地址值不能达到我们实际的要求,则需要重写HashaCode方法使其比较属性值
【API中有一些类已经重写了HashaCode,给出了比较规则,如:String:数值大小、字符串长度 ]
public class Demo1 {public static void main(String[] args) {HashSet<String> hs = new HashSet<>();hs.add("hello");hs.add("world");hs.add("java");hs.add("java");hs.add("java");for (String h : hs) {System.out.println(h);}}
}
打印结果:
--------------------------------------------------------------
world
java
hello
【未重写的类,如:我们自定义的类,则需要去类中重写HashC ode方法】
public class Demo1 {public static void main(String[] args) {HashSet<Student1> hs = new HashSet<>();Student1 s1 = new Student1("张三", 18);Student1 s2 = new Student1("李四", 18);Student1 s3 = new Student1("张三", 18);hs.add(s1);hs.add(s2);hs.add(s3);for(Student1 student : hs){System.out.println(student);}}
}class Student {private String name;private int age;public Student(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Student student = (Student) o;if (age != student.age) return false;return Objects.equals(name, student.name);}@Overridepublic int hashCode() {int result = name != null ? name.hashCode() : 0;result = 31 * result + age;return result;}
}
打印结果:
------------------------------------------------------------
Student{name='张三', age=18}
Student{name='李四', age=18}
3.底层原理【链表,数组,[链表满8为]红黑树】
计算哈希值 : 根据元素的哈希数和数组的长度取余得到存入的位置 如:21501220%16
注:两种Set实现类的选择:【如果你需要得到一个有序的结果时就应该使用TreeMap(因为HashMap中元素的排列顺序是不固定的)。除此之外,由于HashMap有更好的性能,所以大多不需要排序的时候我们会使用HashMap】