javaSE基础知识——day14 collection之set集合的使用:HashSet、LinkedHashSet、TreeSet使用案例

Set集合概述及特点

A:Set集合概述及特点: 通过API查看即可
B: 案例演示: 无序(存储和取出的顺序)和唯一

案例一:

import java.util.Collection;
import java.util.HashSet;

public class SetDemo {
    public static void main(String[] args) {
        //Collection List 元素有序,允许元素重复
        //Set 元素唯一    一个不包含重复元素的 collection
        //HashSet 元素唯一,无序(存取顺序不一致)
        //HashSet 底层数据结构是哈希表:是元素为链表的数组,具有链表和数组的特点  像新华字典(JDK1.7)
        //HashSet()
        //构造一个新的空 set,其底层 HashMap 实例的默认初始容量是 16,加载因子是 0.75。
        HashSet<String> set = new HashSet<>();
        set.add("林心如");
        set.add("杨超越");
        set.add("黎姿");
        set.add("黎姿");
        set.add("刘亦菲");
        set.add("李易峰");
        for (String s : set) {
            System.out.println(s);
        }

    }
}

黎姿
林心如
杨超越
刘亦菲
李易峰

在这里插入图片描述
案例一:

import java.util.HashSet;

public class SetDemo2 {
    public static void main(String[] args) {
        HashSet<Integer> set = new HashSet<>();
        set.add(100);


        //   public HashSet() {
        //    map = new HashMap<>();
        //}


        //public boolean add (E e){
        //    return map.put(e, PRESENT) == null;
        //}

        //public V put (K key, V value){
        //    return putVal(hash(key), key, value, false, true);
        //}


        //static final int hash (Object key){
        //    int h;
        //    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
        //}


        set.add(200);
        set.add(100);
        set.add(300);
        set.add(90);
        set.add(109);
        for (Integer integer : set) {
            System.out.println(integer);
        }
    }
}
结果:
100
200
90
300
109

HashSet保证元素唯一性

  • HashSet 底层数据结构是哈希表. HashSet 不是线程安全的 集合元素可以是 null
  • ​哈希表:是一个元素为链表的数组,综合了数组和链表的优点 (像新华字典一样) (JDK1.7之前)
  • 当向 HashSet 集合中存入一个元素时,HashSet 会调用该对象的 hashCode() 方法来得到该对象的 hashCode 值,
    然后根据 hashCode 值决定该对象在 HashSet 中的存储位置。
  • HashSet 集合判断两个元素相等的标准:
    两个对象通过 hashCode() 方法比较相等,并且两个对象的 equals() 方法返回值也相等。
    结论:HashSet 保证元素唯一性是靠元素重写hashCode()和equals()方法来保证的,如果不重写则无法保证。

案例一:

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 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 hashCode() {
    //    //张三  23   4+23*11
    //    //张三  23   4+23*11
    //    //张三  23   4+24
    //    //李四  24   3+24*11
    //
    //    return this.name.hashCode() + this.age * 11;
    //}
    //
    //@Override
    //public boolean equals(Object obj) {
    //
    //    System.out.println(this + "===" + obj);
    //    if (this == obj) {
    //        return true;
    //    }
    //    if (!(obj instanceof Student)) {
    //        return false;
    //    }
    //    Student student = (Student) obj;
    //
    //    return this.name.equals(student.name) && this.age == student.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);
    }
}


import java.util.HashMap;
import java.util.HashSet;

public class MyTest {
    public static void main(String[] args) {
        //HashSet集合能够保证元素的唯一性,是靠元素重写hashCode()方法和equals方法来保证的,如果元素不重写则无法保证
        //HashSet 底层用的是HashMap来存的
        Student s1 = new Student("王五", 25);
        Student s2 = new Student("王五", 25);
        Student s3 = new Student("王五", 25);
        Student s4 = new Student("王五", 252);
        Student s5 = new Student("王五2", 235);
        Student s6 = new Student("王五3", 25);
        Student s7 = new Student("王五4", 2665);
        Student s8 = new Student("王五5", 285);
        Student s9 = new Student("王五6", 285);
        Student s10 = new Student("王五7", 255);
        HashSet<Student> hashSet = new HashSet<>();
        hashSet.add(s1);
        hashSet.add(s2);
        hashSet.add(s3);
        hashSet.add(s4);
        hashSet.add(s5);
        hashSet.add(s6);
        hashSet.add(s7);
        hashSet.add(s8);
        hashSet.add(s9);
        hashSet.add(s10);
        for (Student student : hashSet) {
            System.out.println(student.getName() + "==" + student.getAge());
        }
    }
}


LinkedHashSet的概述和使用

数据结构 有两个 链表和哈希表
链表保证有序 哈希表保证元素唯一
A:LinkedHashSet的概述: 元素有序 , 并且唯一
B:案例演示: LinkedHashSet的特点

案例一:
// LinkedHashSet 底层数据结构是链表和哈希表,元素有序且唯一 ,链表保证了元素有序,哈希表保证了元素

import java.util.LinkedHashSet;

public class MyTest {
    public static void main(String[] args) {
        // LinkedHashSet 底层数据结构是链表和哈希表,元素有序且唯一 ,链表保证了元素有序,哈希表保证了元素
        LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>();
        linkedHashSet.add("A");
        linkedHashSet.add("B");
        linkedHashSet.add("D");
        linkedHashSet.add("E");
        linkedHashSet.add("C");
        linkedHashSet.add("E");
        linkedHashSet.add("C");
        linkedHashSet.add("E");
        linkedHashSet.add("C");

        for (String s : linkedHashSet) {
            System.out.println(s);
        }
    }
}

结果:
A
B
D
E
C
## TreeSet概述及使用
A: TreeSet集合的特点:底层数据结构是二叉树,元素唯一,他最大的特点是能够对元素进行排序
排序:
a:	自然排序
b: 使用比较器排序
到底使用的是哪一种的排序取决于,构造方法.

TreeSet 排序方式分为 自然排序和比较器排序
具体用哪种排序,根据你使用的构造方法,用空参构造,那么就使用的是自然排序
有参构造,可以使用比较器来排序
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190719132157851.?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xhbGFNYXJyeQ==,size_16,color_FFFFFF,t_70)
## TreeSet自然排序的原理和图解

A:画图演示:	TreeSet保证元素唯一和自然排序的原理和图解
二叉树的数据结构 先存入一个树根 分两个叉
存储元素时 跟树根比较 小的放在左边 大的放在右边
如果相等就不存储
取的时候按照 左中右的顺序来取
案例一:
用自然排序对年龄进行排序,对名字进行排序
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190719132313962.?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xhbGFNYXJyeQ==,size_16,color_FFFFFF,t_70)

package day20190719.study01.treeset;

import java.util.TreeSet;

/**

  • @description: treeset自然排序,使用类空参构造,对名字和年龄进行排序

  • @author: @李小白

  • @create: 2019-07-19 09:52

  • 重写Comparable的compareTo方法进行排序
    */
    public class Demo01 {
    public static void main(String[] args) {
    TreeSet 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));
     for (Student studnt : treeSet) {
         System.out.println(studnt);
     }
    

    }
    }

package day20190719.study01.treeset;

/**

  • @description: 学生共用类

  • @author: @李小白

  • @create: 2019-07-19 09:49
    */
    public class Student implements Comparable{
    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.age-student.age;
    //int num2=num0?this.name.compareTo(student.name):num;
    //根据姓名长度进行排序
    int num=this.name.length()-student.name.length();
    int mun2=num
    0?this.name.compareTo(student.name):num;
    //姓名长度如果一致,还要根据年龄大小进行排序
    int nun3=mun2==0?this.age-student.age:mun2;
    return nun3;
    }

}

## TreeSet比较器排序的原理及代码实现

A:案例演示:	TreeSet保证元素唯一和比较器排序的原理及代码实现
在创建TreeSet对象的时候,传递一个比较器对象
B: 按照年龄进行排序

案例一:
案例二:
用比比较器排序,对名字进行排序,年龄进行排序

package day20190719.study01.treeset;

import java.util.Comparator;
import java.util.TreeSet;

/**

  • @description: treeSet的比较排序

  • @author: @李小白

  • @create: 2019-07-19 10:09
    */
    public class Demo02 {
    public static void main(String[] args) {
    TreeSet treeSet = new TreeSet<>(new Comparator() {
    @Override
    public int compare(Student s1, Student s2) {
    //根据年龄大小进行排序
    //int num=s1.getAge()-s2.getAge();
    //int num2=num0?s1.getName().compareTo(s2.getName()):num;
    //根据姓名长短进行排序
    int num1=s1.getName().length()-s2.getName().length();
    int num2=num1
    0?s1.getName().compareTo(s2.getName()):num1;
    int num3=num1==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);
     }
    

    }
    }

案例三:
new ArrayList<>()排序的另一种排序

import java.util.ArrayList;
import java.util.Comparator;

public class MyTest {
public static void main(String[] args) {
ArrayList integers = new ArrayList<>();
integers.add(21000000);
integers.add(2210);
integers.add(2130);
integers.add(2150);
integers.add(2150);
integers.add(21770);
integers.add(21550);
integers.sort(new Comparator() {
@Override
public int compare(Integer a, Integer b) {
return a-b;
}
});

    System.out.println(integers);


}

}

import java.util.Arrays;
import java.util.Comparator;

public class MyTest2 {
public static void main(String[] args) {
Integer[] arr = {2, 4, 0, 1, 40, 24};
// Arrays.sort(arr);
Arrays.sort(arr, new Comparator() {
@Override
public int compare(Integer a, Integer b) {
return -(a - b);
}
});
System.out.println(Arrays.toString(arr));
}
}

## 产生10个1-20之间的随机数要求随机数不能重复

A:案例演示
需求:编写一个程序,获取10个1至20的随机数,要求随机数不能重复。
并把最终的随机数输出到控制台。
选HashSet 可以不重复
选TreeSet 不重复还可以排序
分析:
a: 定义一个HashSet集合
b: 产生随机数,把随机数添加到集合中
c: 判断集合的长度,使用while循环实现

案例:
//A:
//案例演示
//需求:编写一个程序,获取10个1至20的随机数,要求随机数不能重复。

package day20190719.study01.treeset;

import java.util.LinkedHashSet;
import java.util.Random;
import java.util.TreeSet;

/**

  • @description: treese用随机数编写
  • @author: @李小白
  • @create: 2019-07-19 10:34
  • //A:
  •     //案例演示
    
  •     //需求:编写一个程序,获取10个1至20的随机数,要求随机数不能重复。
    
  •     //并把最终的随机数输出到控制台。
    
  •     //选HashSet 可以不重复
    
  •     //选TreeSet 不重复还可以排序
    

*/
public class Demo03 {
public static void main(String[] args) {
Random random = new Random();//随机数
TreeSet integers = new TreeSet<>();//获取不能重复的

    while (integers.size()<10) {//长度就是10
        int i = random.nextInt(21);//获取1-20个随机数
        integers.add(i);//输出不能重复的10个
    }
    System.out.println(integers);
}

}

键盘录入学生信息按照总分排序后输出在控制台

A:案例演示:	需求:键盘录入3个学生信息(姓名,语文成绩,数学成绩,英语成绩),按照总分从高到低输出到控制台。
/**
* 步骤:
* a: 自定义一个学生类
* b: 创建一个TreeSet集合对象(使用比较器进行排序)
* c: 键盘录入学生的数据,然后把学生的数据封装成一个学生对象,把学生对象添加到集合中
* d: 遍历集合
*/
案例:

package day20190719.study01.treeset;

/**

  • @description: 定义学生的成绩和总分

  • @author: @李小白

  • @create: 2019-07-19 11:26
    */
    public class Student02 {
    private String name;
    private int chineseScore;
    private int mathScore;
    private int englishScore;

    public Student02() {
    }

    public Student02(String name, int chineseScore, int mathScore, int englishScore) {
    this.name = name;
    this.chineseScore = chineseScore;
    this.mathScore = mathScore;
    this.englishScore = englishScore;
    }

    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 getEnglishScore() {
    return englishScore;
    }

    public void setEnglishScore(int englishScore) {
    this.englishScore = englishScore;
    }
    public int getTotalScore(){
    return this.chineseScore+this.mathScore+this.englishScore;
    }

}

package day20190719.study01.treeset;

import java.util.Comparator;
import java.util.Scanner;
import java.util.TreeSet;

/**

  • @description: 请输入三个学生的成绩并且打印出总分

  • @author: @李小白

  • @create: 2019-07-19 11:04
    */
    public class Demo04 {
    public static void main(String[] args) {
    TreeSet treeSet = new TreeSet<>(new Comparator() {
    @Override
    public int compare(Student02 s1, Student02 s2) {
    int num=s2.getTotalScore()-s1.getTotalScore();
    int num2=num==0?s1.getName().compareTo(s2.getName()):num;
    return num2;
    }
    });

     for (int i = 1; i <= 3; i++) {
         Student02 student = new Student02();
         Scanner sc = new Scanner(System.in);
         System.out.println("请输入第"+i+"个学生的姓名");
         String userName = sc.nextLine();
         student.setName(userName);
         System.out.println("请输入第"+i+"个学生的语文成绩");
         int ywScore = sc.nextInt();
         student.setChineseScore(ywScore);
         System.out.println("请输入第"+i+"个学生的数学成绩");
         int sxScore = sc.nextInt();
         student.setMathScore(sxScore);
         System.out.println("请输入第"+i+"个学生的英语成绩");
         int yyScore = sc.nextInt();
         student.setEnglishScore(yyScore);
         treeSet.add(student);
     }
     System.out.println("序号\t姓名\t语文\t数学\t英语\t总分");
     int index=1;
     for (Student02 stu : treeSet) {
         System.out.println(index + "\t\t" +stu.getName()+"\t\t"+ stu.getChineseScore() + "\t\t" + stu.getMathScore() + "\t\t" + stu.getEnglishScore() + "\t\t" + stu.getTotalScore());
         index++;
     }
    

    }
    }

结果:
序号	姓名	语文	数学	英语	总分
1		李*		100		120		120		340
2		李**		100		100		100		300
3		章*		10		50		50		110

## set集合总结

//Set :底层数据结构是二叉树,元素唯一且可以对元素进行排序
// HashSet 底层数据结构是哈希表(数组+链表JDK1.7 JDK 数组+链表+二叉树) 元素无序(存取顺序不一致) 元素唯一
//唯一性要靠元素重写hashCode方法和equals方法来保证的
//重写hashCode是为了确定该元素在哈希表中的位置,我们合理重写hashCode可以减少碰撞
//重写equals是为了比较内容
// LinkedHashSet 底层数据结构是链表和哈希表 ,元素有序且唯一,链表保证了有序,哈希表保证了唯一
//TreeSet 底层数据结构是二叉树 他的特点唯一且能够对元素进行排序
//排序方式:自然排序和比较器排序
//如果用的无参构造,那么就使用自然排序,使用自然排序,对元素有要求,要求元素实现 Comparable接口重写compareTo方法
//根据此方法返回值的正负1、 0 来决定元素的排列位置
//使用有参构造,用的就是比较器,需要传入一个比较器 Comparator 重写里面的 compare 这个比较方法,根据此方法返回值的正1、 0 来决定元素的排列位置 Comparator比较器,其他一些类在调用sort()方法时也可以用

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值