HashSet,LinkedHashSet,TreeSet
1.HashSet
注意事项2:千万不要设置set修改hashset属性值,很可能就不满足不重复的特性了
/*
HashSet:
概述:
底层数据结构是哈希表
它不保证迭代顺序,特别是它不保证该顺序恒久不变 (无序的)。
允许存储 null 元素。
不同步
*/
public class HashSetDemo1 {
public static void main(String[] args) {
HashSet<String> set = new HashSet<>();
set.add("allen");
set.add("beyonce");
set.add("catalina");
set.add("diana");
set.add("allen");
set.add("allen");
set.add(null);
set.add(null);
set.add(null);
System.out.println(set);
}
}
/*
构造方法:
HashSet():数组大小默认为16,加载因子默认为0.75f
HashSet(Collection<? extends E> c)
HashSet(int initialCapacity):
JDK中HashMap数组的大小是2^n,所以数组的大小为大于等于initialCapacity的最小的2^n
加载因子:0.75f
HashSet(int initialCapacity, float loadFactor)
*/
public class HashSetDemo2 {
public static void main(String[] args) {
// HashSet set = new HashSet();
// HashSet set = new HashSet(20);
// HashSet set = new HashSet(20, 10f);
// HashSet(Collection<? extends E> c)
/*List<Character> list = Arrays.asList('A', 'A', 'B', 'B', 'C');
HashSet<Character> set = new HashSet<>(list);
System.out.println(set);*/
}
}
/*
HashSet 是如何保证元素的唯一性的呢?
Set存储的元素是作为Map的key,而Map的key是唯一的
它依赖于存储元素的两个方法: int hashCode() & boolean equals(Object obj)
练习:
HashSet存储自定义对象Student(name, age)
如果name和age都相等,那么我们就认为两个对象相等。
注意事项:千万不要修改 HashSet 元素的属性值!
*/
public class HashSetDemo3 {
public static void main(String[] args) {
HashSet<Student> set = new HashSet<>();
Student s1 = new Student("刘亦菲", 16);
Student s2 = new Student("刘亦菲", 16);
Student s3 = new Student("刘亦菲", 16);
Student s4 = new Student("小龙女", 22);
Student s5 = new Student("花木兰", 18);
Student s6 = new Student("赵灵儿", 17);
set.add(s1);
set.add(s2);
set.add(s3);
set.add(s4);
set.add(s5);
set.add(s6);
/*System.out.println(s1.equals(s2));
System.out.println(s1.equals(s3));*/
/*System.out.println(set.size()); // 4
System.out.println(set);*/
// 修改s4的属性值
s4.setName("刘亦菲");
s4.setAge(16);
System.out.println(set.size()); // ?
System.out.println(set);
}
}
重写了equals也一定要重写hashCode方法
package com.cskaoyan.set;
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 void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
@Override
public boolean equals(Object obj) {
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
Student s = (Student) obj;
return age == s.age && Objects.equals(name, s.name);
}
@Override
public int hashCode() {
int h = 0;
h = h * 31 + age;
h = h * 31 + Objects.hashCode(name);
return h;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
2.TreeSet
public class TreeSetDemo1 {
public static void main(String[] args) {
// TreeSet()
TreeSet<Teacher> set = new TreeSet<>();
Teacher t1 = new Teacher("风华大叔", 38);
Teacher t2 = new Teacher("蓝胖", 88);
Teacher t3 = new Teacher("严汉", 20);
Teacher t4 = new Teacher("张帅", 19);
Teacher t5 = new Teacher("黑大帅", 18);
Teacher t6 = new Teacher("黑大帅", 18);
set.add(t1);
set.add(t2);
set.add(t3);
set.add(t4);
set.add(t5);
set.add(t6);
System.out.println(set.size()); //
System.out.println(set);
}
}
package com.cskaoyan.set;
public class Teacher implements Comparable<Teacher> {
private String name;
private int age;
public Teacher() {
}
public Teacher(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Teacher{" +
"name='" + name + '\'' +
", age='" + age + '\'' +
'}';
}
@Override
public int compareTo(Teacher t) {
// 先按年龄比较,再按姓名比较
int cmp = age - t.age;
cmp = cmp != 0 ? cmp : name.compareTo(t.name);
return cmp;
}
}
3.LinkedHashSet
可以存储null
从双向链表那体现顺序
/*
LinkedHashSet:
HashSet 的子类
底层是HashMap & 双向链表
HashMap 保证了元素的唯一性。
链表定义了迭代的顺序,按照元素的插入顺序进行迭代。
不同步。
注意事项:
它依赖于存储元素的两个方法: int hashCode() & boolean equals(Object obj)
千万不要修改 HashSet 元素的属性值!
*/
public class LinkedHashSetDemo1 {
public static void main(String[] args) {
LinkedHashSet<String> set = new LinkedHashSet<>();
set.add("catalina");
set.add("diana");
set.add("allen");
set.add("beyonce");
set.add("allen");
set.add("allen");
set.add(null);
set.add(null);
set.add(null);
System.out.println(set);
}
}
练习:将成绩存入IO文件
package com.cskaoyan.exercise;
public class Student {
private String name;
private int chinese;
private int math;
private int english;
public Student() {
}
public Student(String name, int chinese, int math, int english) {
this.name = name;
this.chinese = chinese;
this.math = math;
this.english = english;
}
public String getName() {
return name;
}
public int getChinese() {
return chinese;
}
public int getMath() {
return math;
}
public int getEnglish() {
return english;
}
public int totalScore() {
return chinese + math + english;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", chinese=" + chinese +
", math=" + math +
", english=" + english +
'}';
}
}
package com.cskaoyan.exercise;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Comparator;
import java.util.TreeSet;
/*
录入4个学生信息 (姓名,语文成绩,数学成绩,英语成绩),并按照指定的格式,总分从高到低,输出到文件。
1.创建学生类
2.创建学生对象
3.添加到TreeSet中,按照总分从高到低进行排序
4.把TreeSet中的学生信息输出到文件
*/
public class Ex1 {
public static void main(String[] args) {
Student s1 = new Student("刘亦菲", 100, 100, 100);
Student s2 = new Student("迪丽热巴", 90, 90, 90);
Student s3 = new Student("古力娜扎", 90, 90, 90);
Student s4 = new Student("佟丽娅", 95, 95, 95);
TreeSet<Student> set = new TreeSet<>(new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
int cmp = s2.totalScore() - s1.totalScore();
cmp = cmp != 0 ? cmp : s2.getChinese() - s1.getChinese();
cmp = cmp != 0 ? cmp : s2.getMath() - s1.getMath();
// cmp = cmp != 0 ? cmp : s2.getEnglish() - s1.getEnglish();
cmp = cmp != 0 ? cmp : s2.getName().compareTo(s1.getName());
return cmp;
}
});
set.add(s1);
set.add(s2);
set.add(s3);
set.add(s4);
System.out.println(set.size());
System.out.println(set);
// 把TreeSet中的学生信息输出到文件
try (PrintWriter out = new PrintWriter(new FileWriter("student.txt"))) {
out.println("姓名\t语文\t数学\t英语\t总分");
for(Student s : set) {
out.println(s.getName() + "\t" + s.getChinese() + "\t" + s.getMath() +
"\t" + s.getEnglish() + "\t" + s.totalScore());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}