Set集合概述及特点
- Set集合概述:
是Collection集合的子集合,类似于一个容器,可以装取数据 - Set集合特点:
通过重写equals()而保证了元素的唯一性
HashSet集合的概述及特点
- HashSet集合的概述:
是Set集合的子集合 - HashSet集合的特点
底层数据结构是哈希表,HashSet 不是线程安全的 集合元素可以是 null
哈希表:是一个元素为链表的数组,综合了数组和链表的优点 (JDK1.7之前) - 如何保证元素的唯一性:
当向 HashSet 集合中存入一个元素时,HashSet 会调用该对象的 hashCode() 方法来得到该对象的 hashCode 值,
然后根据 hashCode 值决定该对象在 HashSet 中的存储位置。
HashSet 集合判断两个元素相等的标准:
两个对象通过 hashCode() 方法比较相等,并且两个对象的 equals() 方法返回值也相等。
结论:HashSet 保证元素唯一性是靠元素重写hashCode()和equals()方法来保证的,如果不重写则无法保证。
HashSet集合的案例演示
public class MyTest {
public static void main(String[] args) {
HashSet<String> set = new HashSet<>();
set.add("aaa");
set.add("bbb");
set.add("ccc");
set.add("刘德华");
set.add("郭富城");
set.add("黎明");
set.add("张学友");
set.add("刘德华");
set.add("郭富城");
set.add("黎明");
set.add("张学友");
for (String s : set) {
System.out.println(s);
}
}
}
//String类默认重写了equals()方法,所以可以保证元素的唯一性,但打印出的结果是无序的,HashSet的特点就是无序且唯一
LinkedHashSet的概述和使用
- LinkedHashSet的概述:
数据结构 有两个 链表和哈希表
链表保证有序 哈希表保证元素唯一
元素有序 , 并且唯一,线程不安全,效率高 - LinkedHashSet的使用
public class MyTest2 {
public static void main(String[] args) {
LinkedHashSet<String> strings = new LinkedHashSet<>();
strings.add("aaa");
strings.add("bbb");
strings.add("ccc");
strings.add("ddd");
strings.add("eee");
strings.add("fff");
strings.add("aaa");
strings.add("bbb");
strings.add("ccc");
strings.add("ddd");
strings.add("eee");
strings.add("fff");
for (String string : strings) {
System.out.println(string);
}
ArrayList<String> strings1 = new ArrayList<>();
strings1.add("aaaaa");
strings1.add("bbbbb");
strings1.add("ccc");
strings1.add("dddd");
strings1.add("eeee");
strings1.add("aaaaa");
strings1.add("bbbbb");
strings1.add("ccc");
strings1.add("dddd");
strings1.add("eeee");
HashSet<String> strings2 = new HashSet<>(strings1);
System.out.println(strings2);
LinkedHashSet<String> strings3 = new LinkedHashSet<>(strings1);
System.out.println(strings3);
}
}
TreeSet的概述及使用
- TreeSet的概述:
TreeSet是Set集合的子集合,可以存取元素并排序 - TreeSet的特点:
TreeSet集合的特点: 元素唯一,并且可以对元素进行排序
排序:
a: 自然排序
b: 使用比较器排序
到底使用的是哪一种的排序取决于,构造方法.
注意:使用TreeSet集合进行元素的自然排序,那么对元素有要求,要求这个元素
必须实现Comparable接口 否则无法进行自然排序
保证元素的唯一性是靠compareTo方法的返回值来确定如果返回0 表示两个元素相等,则不重复存储 - TreeSet的案例演示:
Integer类自然排序:
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet<Integer> treeSet = new TreeSet<>();
treeSet.add(20);
treeSet.add(18);
treeSet.add(23);
treeSet.add(22);
treeSet.add(17);
treeSet.add(24);
treeSet.add(19);
treeSet.add(18);
treeSet.add(24);
System.out.println(treeSet);
}
}
//Integer类默认重写了compareTo()方法,所以可实现自然排序
自定义类的自然排序:
public class Student implements Comparable<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 int compareTo(Student student) {
//根据姓名的长度来排序
//如果长度一样,那么还得比较姓名内容
int num = this.name.length() - student.name.length();
int num2=num==0?this.name.compareTo(student.name):num;
//当长度一样,内容一样,还得比较年龄
int num3=num2==0?this.age-student.age:num2;
return num3;
}
}
-------------------------------------------------------------------------------------------
public class MyTest2 {
public static void main(String[] args) {
TreeSet<Student> treeSet = new TreeSet<>();
treeSet.add(new Student("张三士大夫士大夫", 23));
treeSet.add(new Student("张三是非得失", 23));
treeSet.add(new Student("李四大幅度发", 23));
treeSet.add(new Student("王五大幅度发", 20));
treeSet.add(new Student("周六的", 30));
treeSet.add(new Student("田七大幅度", 23));
treeSet.add(new Student("李白大幅度发", 33));
treeSet.add(new Student("刘星大幅度发", 63));
treeSet.add(new Student("夏雨", 78));
treeSet.add(new Student("张子豪", 53));
treeSet.add(new Student("张子豪", 50));
//按照姓名长度来拍
for (Student student : treeSet) {
System.out.println(student);
}
}
}
比较器排序:
public class MyTest2 {
public static void main(String[] args) {
//比较器排序:就是我们在创建TreeSet对象时,给他传入一个比较器,重写比较器里面的compare方法,根据此方法的返回值的正负 0
//来决定元素的放置顺序
TreeSet<Student> treeSet = new TreeSet<>(new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
//根据姓名长度来排序
int num = s1.getName().length() - s2.getName().length();
int num2=num==0?s1.getName().compareTo(s2.getName()):num;
int num3=num2==0?s1.getAge()-s2.getAge():num2;
return num3;
}
});
treeSet.add(new Student("张三士大夫士大夫", 23));
treeSet.add(new Student("张三是非得失", 23));
treeSet.add(new Student("李四大幅度发", 23));
treeSet.add(new Student("王五大幅度发", 20));
treeSet.add(new Student("周六的", 30));
treeSet.add(new Student("田七大幅度", 23));
treeSet.add(new Student("李白大幅度发", 33));
treeSet.add(new Student("刘星大幅度发", 63));
treeSet.add(new Student("夏雨", 78));
treeSet.add(new Student("张子豪", 53));
for (Student student : treeSet) {
System.out.println(student);
}
}
}
产生10个1-20之间的随机数要求随机数不能重复
public class MyTest {
public static void main(String[] args) {
//A:
//案例演示
//需求:编写一个程序,获取10个1至20的随机数,要求随机数不能重复。
//并把最终的随机数输出到控制台。
//选HashSet 可以不重复
//选TreeSet 不重复还可以排序
TreeSet<Integer> treeSet = new TreeSet<>();
Random random = new Random();
while (treeSet.size()<10){
int num = random.nextInt(20) + 1;
treeSet.add(num);
}
System.out.println(treeSet);
}
}
键盘录入学生信息按照总分排序后输出在控制台
需求:键盘录入5个学生信息(姓名,语文成绩,数学成绩,英语成绩)
按照总分从高到低输出到控制台
public class Student {
private String name;
private int chineseScore;
private int mathScore;
private int englishScre;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getChineseScore() {
return chineseScore;
}
public void setChineseScore(int chineseScore) {
this.chineseScore = chineseScore;
}
public int getMathScore() {
return mathScore;
}
public void setMathScore(int mathScore) {
this.mathScore = mathScore;
}
public int getEnglishScre() {
return englishScre;
}
public void setEnglishScre(int englishScre) {
this.englishScre = englishScre;
}
//获取总分的方法
public int getTotalScore(){
return this.chineseScore+this.mathScore+this.englishScre;
}
}-------------------------------------------------------------------------------public class MyTest {
public static void main(String[] args) {
TreeSet<Student> treeSet = new TreeSet<>(new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
//按照总分高低来排序学生对象
int num = s1.getTotalScore() - s2.getTotalScore();
//总分一样还得比较姓名
int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
return -num2;
}
});
String regex="[0-9]{1,2}|(100)";
for (int i = 1; i <= 5; i++) {
Student student = new Student();
Scanner sc = new Scanner(System.in);
System.out.println("请输入第" + i + "个学生的姓名");
String username = sc.nextLine();
student.setName(username);
System.out.println("请输入第" + i + "个学生的语文成绩:0-100");
String s = sc.nextLine();
while (!s.matches(regex)){
System.out.println("输入成绩范围有误,请重新输入");
s = sc.nextLine();
}
student.setChineseScore(Integer.valueOf(s));
System.out.println("请输入第" + i + "个学生的数学成绩:0-100");
String s1 = sc.nextLine();
student.setMathScore(Integer.valueOf(s1));
while (!s1.matches(regex)){
System.out.println("输入成绩范围有误,请重新输入");
s1 = sc.nextLine();
}
System.out.println("请输入第" + i + "个学生的英语成绩:0-100");
String s2 = sc.nextLine();
student.setEnglishScre(Integer.valueOf(s2));
while (!s2.matches(regex)){
System.out.println("输入成绩范围有误,请重新输入");
s2 = sc.nextLine();
}
//把学生对象添加到集合中
treeSet.add(student);
}
//将学生信息打印到控制台
//打印表头
System.out.println("序号"+"\t"+"姓名"+"\t"+"语文"+"\t"+"数学"+"\t"+"外语"+"\t"+"总分");
int index=1;
for (Student student : treeSet) { System.out.println(index+"\t"+student.getName()+"\t"+student.getChineseScore()+"\t"+student.getMathScore()+"\t"+student.getEnglishScre()+"\t"+student.getTotalScore());
index++;
}
}
}