概述及特点 一个不包含重复元素的Collection。更确切地讲,set不包含满足eq.equals(e2)的元素e1和e2,并且最包含一个null元素
import java.util.HashSet; public class MyTest2 { public static void main(String[] args) { HashSet<Integer> integers = new HashSet<>(); integers.add(10); integers.add(12); integers.add(15); integers.add(null); integers.add(14); integers.add(10); integers.add(20); for (Integer integer : integers) { System.out.println(integer); } } } 因为Set集合有唯一性,所以就只存储了一个10,遍历的时候也只有一个10 而且它是无序的存储的顺序和遍历的顺序并不一致
HashSet底层数据结构是哈希表。HashSet不是线程安全的,集合元素可以是null
哈希表:是一个元素为链表的数组,综合了数组和链表的优点
当向HashSet集合中存入一个元素是,HashSet会调用对象的hashCode()方法来得到该对象的hashCode值 然后根据hashCode值决定对象在HashSet中的存储位置 HashSet集合判断两个元素相等的标准: 两个对象是通过hashCode()方法比较相等,并且两个对象的equals()方法的返回值也相等。 结论:HashSet保证元素唯一性是靠元素重写hashCode()和equals()方法来保证的,如果不重写则无法保证。 @Override public int hashCode() { // return 0; // 因为成员变量值影响了哈希值,所以我们把成员变量值相加即可 // return this.name.hashCode() + this.age; // 看下面 //s1:name.hashCode()=40,age=30 //s2:name.hashCode()=20,age=50 //尽可能的区分,我们可以把它们随变乘以一些整数 return this.name.hashCode() + this.age * 15; } // @Override // public boolean equals(Object obj) { // // System.out.println(this + "---" + obj); // if (this == obj) { // return true; // } // // if (!(obj instanceof Student)) { // return false; // } // // Student s = (Student) obj; // return this.name.equals(s.name) && this.age == s.age; // } // // @Override // public String toString() { // return "Student [name=" + name + ", age=" + age + "]"; // }
1.存储自定义对象并保证元素的唯一性 如果两个对象的成员变量都相同就认为是同一个对象 自定义类: import java.util.Objects; public class Student { int age; String name; public Student(){ } public Student(int age,String name){ this.age=age; this.name=name; } @Override public String toString() { return "Student{" + "age=" + age + ", name='" + name + '\'' + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Student student = (Student) o; return age == student.age && Objects.equals(name, student.name); } @Override public int hashCode() { return Objects.hash(age, name); } } 测试类: import java.util.HashSet; public class MyTest { public static void main(String[] args) { HashSet<Student> students = new HashSet<>(); students.add(new Student(15,"张三")); students.add(new Student(15,"李四")); students.add(new Student(16,"张三")); students.add(new Student(15,"张三")); students.add(new Student(15,"王五")); students.add(new Student(15,"赵六")); for (Student student : students) { System.out.println(student); } } }
1.概述 元素有序且唯一 数据结构有两个 链表和哈希表 链表保证元素有序,哈希表保证元素唯一 2.演示 public class MyTest { public static void main(String[] args) { LinkedHashSet<Student> students = new LinkedHashSet<>(); students.add(new Student(15,"张三")); students.add(new Student(15,"李四")); students.add(new Student(16,"张三")); students.add(new Student(15,"张三")); students.add(new Student(15,"王五")); students.add(new Student(15,"赵六")); for (Student student : students) { System.out.println(student); } } } 输出的结果是去重之后按顺序打印
1.TreeSet集合的特点 元素唯一,并且可以对元素进行排序 排序: a.自然排序 b.使用比较器排序 到底使用哪一种构造方法取决于构造方法 2.演示 TreeSet存储Integer类型的元素并遍历 存储下列元素: 20 , 18 , 23 , 22 , 17 , 24, 19 , 18 , 24 public class MyTest3 { public static void main(String[] args) { TreeSet<Integer> integers = new TreeSet<>(); integers.add(20); integers.add(18); integers.add(23); integers.add(22); integers.add(17); integers.add(24); integers.add(19); integers.add(18); integers.add(24); for (Integer integer : integers) { System.out.println(integer); } } } 对元素进行了去重并且进行了排序
原理: TreeSet保证元素唯一和自然排序的原理和图解 是按照二叉树的数据结构,先存入一个树根,分两个叉 存储元素是,跟树根比较,小的放左边,大的放右边 如果相等就不存储 取得时候按照左中右的顺序来取
图解:
创建学生类 让他们按照年龄排序 次要就是按照名字 自定义类: import java.util.Objects; public class Student implements Comparable<Student>{ int age; String name; public Student(){ } public Student(int age,String name){ this.age=age; this.name=name; } @Override public String toString() { return "Student{" + "age=" + age + ", name='" + name + '\'' + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Student student = (Student) o; return age == student.age && Objects.equals(name, student.name); } @Override public int hashCode() { return Objects.hash(age, name); } @Override public int compareTo(Student student) { int a=this.age-student.age; int b=(a==0)?this.name.compareTo(student.name):a; return b; } } 测试类: import java.util.TreeSet; public class MyTest { public static void main(String[] args) { TreeSet<Student> students = new TreeSet<>(); students.add(new Student(15,"张三")); students.add(new Student(15,"李四")); students.add(new Student(16,"张三")); students.add(new Student(15,"张三")); students.add(new Student(18,"王五")); students.add(new Student(15,"赵六")); for (Student student : students) { System.out.println(student); } } }
import java.util.Comparator; import java.util.TreeSet; public class MyTest { public static void main(String[] args) { TreeSet<Student> students = new TreeSet<>(new Comparator<Student>() { @Override public int compare(Student o1, Student o2) { int a=o1.age-o2.age; int b=(a==0)?o1.name.compareTo(o2.name):a; return b; } }); students.add(new Student(15,"张三")); students.add(new Student(15,"李四")); students.add(new Student(16,"张三")); students.add(new Student(15,"张三")); students.add(new Student(18,"王五")); students.add(new Student(15,"赵六")); for (Student student : students) { System.out.println(student); } } }
编写一个程序,获取10个1至20的随机数,要求随机数不能重复。 并把最终的随机数输出到控制台。 import java.util.HashSet; import java.util.Random; public class MyTest4 { public static void main(String[] args) { HashSet<Integer> integers = new HashSet<>(); Random random = new Random(); while (integers.size()<=10){ integers.add(random.nextInt(20)+1); } for (Integer integer : integers) { System.out.println(integer); } } }
需求:键盘录入3个学生信息(姓名,语文成绩,数学成绩,英语成绩),按照总分从高到低输出到控制台。 自定义类 public class Student implements Comparable<Student> { String name; int chinese; int math; int english; int add; public Student(){ } @Override public String toString() { return name+"\t"+chinese+"\t"+math+"\t"+english+"\t"+add; } public Student(String name, int chinese, int math, int english) { this.name = name; this.chinese = chinese; this.math = math; this.english = english; this.add =chinese+math+english; } @Override public int compareTo(Student o) { int i=this.add-o.add; int a=(i==0)?(this.chinese-o.chinese):i; int b=(a==0)?(this.math-o.math):a; int c=(b==0)?(this.english-o.english):b; int d=(c==0)?(this.name.compareTo(o.name)):c; return d; } } 测试类 import java.util.Scanner; import java.util.TreeSet; public class MyTest1 { public static void main(String[] args) { TreeSet<Student> students = new TreeSet<>(); for (int i=0;i<5;i++){ Scanner sc = new Scanner(System.in); System.out.println("请依次输入学生的姓名,语文成绩,数学成绩,英语成绩"); String name=sc.nextLine(); int chinese=sc.nextInt(); int math=sc.nextInt(); int english=sc.nextInt(); Student student = new Student(name, chinese, math, english); students.add(student); } for (Student student : students) { System.out.println(student); } } }
Set集合也是很重要的集合,它的存储是无序而且唯一的,它也有多个子类,每一个子类都有自己独特的属性