JAVASE基础模块二十五(Set集合)
Set集合
-
Set 集合:元素为一不允许重复
-
HashSet:底层数据结构哈希表(JDK1.7 数组+链表 JDK1.8优化 数组+链表+红黑树 )
-
元素无序(存取元素的顺序不一致) 且唯一(元素不允许重复)
-
HashSet集合保证元素的不重复 重写了hashcode() equals()方法
import java.util.HashSet; public class Settt { public static void main(String[] args) { HashSet<String> s = new HashSet<>(); s.add("x11"); s.add("x22"); s.add("x33"); s.add("x44"); s.add("x55"); s.add("x55"); for (String s1 : s) { System.out.println(s1); } System.out.println("---------------------"); HashSet<Integer> d = new HashSet<>(); d.add(200); d.add(300); d.add(400); d.add(500); d.add(600); d.add(200); d.add(200); for (Integer integer : d) { System.out.println(integer); } } } 运行结果: x11 x22 x33 x44 x55 --------------------- 400 500 200 600 300 进程已结束,退出代码0
-
数据存储
- HashSet 底层是用hashmap来存储的
- 合理的重写hashCode方法 为了减少equals()方法的调用次数 也就是说为了减少碰撞次数
- 未重写hashcode() equals()方法的结果
import java.util.HashSet; public class Stu { public static void main(String[] args) { HashSet<Student> e = new HashSet<>(); e.add(new Student("x1",10)); e.add(new Student("x2",11)); e.add(new Student("x3",12)); e.add(new Student("x4",13)); e.add(new Student("x1",10)); e.add(new Student("x1",11)); for (Student s : e) { System.out.println(s); } } } 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 String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } } 运行结果: Student{name='x1', age=10} Student{name='x1', age=10} Student{name='x3', age=12} Student{name='x2', age=11} Student{name='x4', age=13} Student{name='x1', age=11} 进程已结束,退出代码0
- 重写hashcode() equals()方法过后的结果
@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(name, age); } 运行结果: Student{name='x1', age=11} Student{name='x1', age=10} Student{name='x2', age=11} Student{name='x3', age=12} Student{name='x4', age=13} 进程已结束,退出代码0
-
HashSet 底层是用hashmap来存储的
-
合理的重写hashCode方法 为了减少equals()方法的调用次数 也就是说为了减少碰撞次数
import java.util.HashSet; import java.util.Objects; public class Stu { public static void main(String[] args) { HashSet<Student> e = new HashSet<>(); e.add(new Student("x1",10)); e.add(new Student("x2",11)); e.add(new Student("x3",12)); e.add(new Student("x4",13)); e.add(new Student("x1",10)); e.add(new Student("x1",11)); for (Student s : e) { System.out.println(s); } } } 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 String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } @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(name, age); } }
-
用HashSet去除重复元素
import java.util.ArrayList; import java.util.HashSet; public class QuC { public static void main(String[] args) { ArrayList<Integer> d = new ArrayList<>(); d.add(333); d.add(777); d.add(333); d.add(777); d.add(333); d.add(777); d.add(333); d.add(777); HashSet<Integer> dd = new HashSet<>(d); System.out.println(dd); } } [777, 333] 进程已结束,退出代码0
LinkedHashSet
- LinkedHashSet
- 数据元素有序存储
import java.util.LinkedHashSet;
public class LiHa {
public static void main(String[] args) {
//有序存储
LinkedHashSet<Integer> h = new LinkedHashSet<>();
h.add(333);
h.add(777);
h.add(555);
h.add(1);
h.add(22);
h.add(42);
h.add(82);
h.add(777);
h.add(555);
for (Integer ii : h) {
System.out.print(ii + "\t");
}
}
}
运行结果:
333 777 555 1 22 42 82
Process finished with exit code 0
TreeSet
-
TreeSet 底层数据结构是二叉树 元素为一 且能进行元素排序
import java.util.TreeSet; public class TreeSetdd { public static void main(String[] args) { TreeSet<Integer> h = new TreeSet<>(); h.add(41); h.add(527); h.add(55); h.add(587); h.add(78); h.add(36); h.add(96); h.add(74); h.add(12); h.add(253); h.add(767); h.add(555); h.add(555); h.add(555); h.add(555); for (Integer ii : h) { System.out.print(ii+"\t"); } } } 运行结果: 12 36 41 55 74 78 96 253 527 555 587 767 进程已结束,退出代码0
-
排序
- TreeSet 采用的两种排序方式 一种是自然排序 一种是比较器排序
- 自然排序 采用空参构造 自然排序对元素有要求
- 要求元素必须实现一个Comparable接口 重写compareTo(T o)方法
- 根据compareTo(T o)方法的返回值:正 负 0来决定元素在二叉树中的位置
- 比较方式二 比较器new Comparator()
- 自然排序
public class PaiXu { public static void main(String[] args) { //根据学生年龄大小 TreeSet<Student> dd = new TreeSet<>(); dd.add(new Student("x3", 30)); dd.add(new Student("x33", 30)); dd.add(new Student("x5", 50)); dd.add(new Student("x7", 70)); dd.add(new Student("x4", 40)); dd.add(new Student("x6", 60)); dd.add(new Student("x2", 20)); dd.add(new Student("x1", 10)); for (Student s : dd) { System.out.println(s); } } } class Student implements Comparable<Student>{ private String name; private int age; public Student(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override public int compareTo(Student o) { //根据年龄大小进行排序 int num=this.age-o.age; //如果年龄相同 并不能说他们是同一个对象 还得比较姓名是否相同 int num2=num==0?this.name.compareTo(o.name):num; return num2; } } 运行结果: Student{name='x1', age=10} Student{name='x2', age=20} Student{name='x3', age=30} Student{name='x33', age=30} Student{name='x4', age=40} Student{name='x5', age=50} Student{name='x6', age=60} Student{name='x7', age=70} return 0; Student{name='x3', age=30} return 1; Student{name='x3', age=30} Student{name='x5', age=50} Student{name='x7', age=70} Student{name='x4', age=40} Student{name='x6', age=60} Student{name='x2', age=20} Student{name='x1', age=10} return -1; Student{name='x1', age=10} Student{name='x2', age=20} Student{name='x6', age=60} Student{name='x4', age=40} Student{name='x7', age=70} Student{name='x5', age=50} Student{name='x3', age=30}
import java.util.TreeSet; public class PaiXu { public static void main(String[] args) { TreeSet<Student> dd = new TreeSet<>(); dd.add(new Student("xafdagadf3", 30)); dd.add(new Student("xgf33", 30)); dd.add(new Student("弎屲", 50)); dd.add(new Student("弎屲", 70)); dd.add(new Student("屲弎", 70)); dd.add(new Student("xzvxvzcxvc4", 40)); dd.add(new Student("xzcxbbc6", 60)); dd.add(new Student("xsGA2", 20)); dd.add(new Student("xnxgx1", 10)); for (Student s : dd) { System.out.println(s); } } } class Student implements Comparable<Student>{ private String name; private int age; public Student(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override public int compareTo(Student o) { //当姓名长度一样 不能说明是同一个对象 int num=this.name.length()-o.name.length(); //当姓名长度一样时 需要比较姓名内容 int num2=num==0?this.name.compareTo(o.name):num; //当姓名长度 姓名内容都一样时 需要比较年龄 int num3=num2==0?this.age-o.age:num2; return num3; } } 运行结果: Student{name='屲弎', age=70} Student{name='弎屲', age=50} Student{name='弎屲', age=70} Student{name='xgf33', age=30} Student{name='xsGA2', age=20} Student{name='xnxgx1', age=10} Student{name='xzcxbbc6', age=60} Student{name='xafdagadf3', age=30} Student{name='xzvxvzcxvc4', age=40} Process finished with exit code 0 return 0; Student{name='x3', age=30} return 1; Student{name='x3', age=30} Student{name='x5', age=50} Student{name='x7', age=70} Student{name='x4', age=40} Student{name='x6', age=60} Student{name='x2', age=20} Student{name='x1', age=10} return -1; Student{name='x1', age=10} Student{name='x2', age=20} Student{name='x6', age=60} Student{name='x4', age=40} Student{name='x7', age=70} Student{name='x5', age=50} Student{name='x3', age=30}
-
比较器new Comparator()
import java.util.Comparator; import java.util.TreeSet; public class BiJiaoQi { public static void main(String[] args) { //排序方式二 比较器 TreeSet<Ren> ee = new TreeSet<>(new Comparator<Ren>() { @Override public int compare(Ren o1, Ren o2) { int num = o1.getAge() - o2.getAge(); int num2 = num == 0 ? o1.getName().compareTo(o2.getName()) : num; return num2; } }); ee.add(new Ren("飒飒的", 24)); ee.add(new Ren("鬼父", 55)); ee.add(new Ren("第三方范德萨", 25)); ee.add(new Ren("范德萨发的", 86)); ee.add(new Ren("规范地方", 13)); ee.add(new Ren("让他一人", 42)); for (Ren ren : ee) { System.out.println(ren); } } } class Ren { private String name; private int age; public Ren(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 String toString() { return "Ren{" + "name='" + name + '\'' + ", age=" + age + '}'; } } 运行结果: Ren{name='规范地方', age=13} Ren{name='飒飒的', age=24} Ren{name='第三方范德萨', age=25} Ren{name='让他一人', age=42} Ren{name='鬼父', age=55} Ren{name='范德萨发的', age=86} Process finished with exit code 0