JAVA高级应用HashSet与TreeSet应用

HashSet与TreeSet

HashSet

HashSet添加字符串
特点:无序(无下标)  不重复
linkedHashSet是HashSet的一个子类
特点:有序 不重复 怎么存的就怎么去出来
public static void fun1(){
    HashSet<String> set = new HashSet<String>();
    boolean b = set.add("a");    //  输出结果为:true
    boolean b1 = set.add("a");   //  输出结果为:false
    set.add("b");
    set.add("b");
    set.add("c");
    set.add("c");
    set.add("d");
    set.add("d");

    System.out.println(set);  //输出结果:a,b,c,d
}
HashSet添加学生对象去重
package com.lanou3g.set;

public class Person {
    private String name;
    private int age;
    public Person() {
        super();
        // TODO Auto-generated constructor stub
    }
    public Person(String name, int age) {
        super();
        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 "[姓名=" + name + ", 年龄=" + age + "]";
    }

    @Override
    public boolean equals(Object obj){
        Person person = Person(obj);
        return this.name.equals(person.getName()) && this.age == person.getAge();
    }

    @Override
    public int hashCode(){
        return 1;
    }
}
系统在Person类中重写equals方法与hashCode方法

public int hashCode() {
        //  31是个质数  只能被1和本身整除  乘法减少公约数

        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)  //  如果两个对象地址一样  
            return true;  //  就返回true
        if (obj == null)  //  如果传进来的对象是空
            return false; //  就返回false
        if (getClass() != obj.getClass())  //  如果两个对象不是一个类创建出来
            return false; //  就返回false           
        Person other = (Person) obj;  //  向下转型(准备调用特有的方法)
        if (age != other.age)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))  //使用字符串类的比较 判断字符串是否相同
            return false;
        return true;
    }
public static void fun2(){
    HashSet<Person> set = new HashSet<Person>();
    set.add(new Person("张三",15));
    set.add(new Person("张三",15));
    set.add(new Person("李四",16));
    set.add(new Person("李四",16));
    set.add(new Person("王五",17));
    set.add(new Person("王五",17));

    for(Person person : set){
        System.out.println(person);    //结果:去重 从小往大排序
    }
}
解释:
set.add()方法自动去重,是因为内部调用了contains()方法,而contains()方法内部又调用了equals()方法,
进行添加的时候,先看对象的hashCode值,不同的对象会有不同的hashCode值,hashCode值不同,默认是两个不同的对象,
而实际进行比较的时候,是看姓名和年龄是否相同,如果相同则认为是同一个对象,为了解决这个矛盾,需要重写hashCode()函数,
使相同姓名与年龄的对象返回的hashCode值一样,在调用hashCode函数后,会调用equals函数,而equals函数比较的是地址,
地址不同,系统也会认为是不同的对象,和现实认为同一对象的情况不符,为了解决这一矛盾,所有要重写equals函数,
在equals函数中比较姓名和年龄,从而通过重写得到与现实情况一致的函数代码.
linkedHashSet
public static void fun3(){
    LinkedHashSet<String> set = new LinkedHashSet<String>();
    set.add("a");
    set.add("1");
    set.add("b");
    set.add("z");
    set.add("a");
    System.out.println(set);  //输出结果:a 1 b z
}
解释
这里之所以不重写hashCode()equals()来去重 ,是因为String是系统类,系统内部已经重写
了equals()方法和hashCode()方法实现去重,不用我们在手动书写
HashSet里面添加Integer对象
//集合长度 < 10 就添加   Integer也重写了HashCode和equals方法
//添加10个1到20之间的随机数
public static void fun4(){
    HashSet<Integer> set = new HashSet<Integer>();
    while(set.size() < 10){
        int num = (int)(Math.random()*(20 - 1 + 1) + 1);
        set.add(num);
    }
    System.out.println(set);
}
输入一个字符串 去掉其中重复字符
public static void fun5(){
    HashSet<Character> set = new HashSet<Character>();
    Scanner sc = new Scanner(System.in);
    System.out.println("请输入一个字符串:");
    String str = scanner.nextLine();
    for(int i = 0; i < str.length(); i++){
        char c = str.charAt(i);   //  自动装箱
        set.add(c);
    }
    System.out.println(set);
}
利用set集合 去除ArrayList集合中的重复元素
//  (操作原ArrayList)
public void fun6(){
    ArrayList<String> array = new ArrayList<String>();
    array.add("a");
    array.add("a");
    array.add("b");
    array.add("b");
    array.add("c");
    array.add("c");
    array.add("d");
    array.add("d");

    LinkedHashSet<String> set = new LinkedHashSet<String>();
    set.addAll(array);
    array.clear();
    list.addAll(set);
    System.out.println(list);
}

TreeSet

特点
无序 不重复 无下标
主要作用:用来排序


使用TreeSet排序的步骤
1.让TreeSet集合中要保存的对象 实现Comparable接口
2.实现compareTo方法
3.在compareTo方法 实现 你要排序的规则
添加方法
public static void fun1(){
    TreeSet<Integer> set = new TreeSet<Integer>();
    set.add(1);
    set.add(2);
    set.add(1);
    set.add(0);
    set.add(8);
    set.add(7);

    System.out.println(set);   //输出结果:0,1,2,7,8
}
示例1:
    //  创建TreeSet集合 保存4个工人
    //  系统给你留了接口Comparable 如果你想通过TreeSet来排序
    //  你就实现这个接口 编写排序规则 系统就会按规则来排序

    实现接口中的唯一的一个方法
    /*
     * 返回0时    表示两个对象是相同的,set中只有一个元素
     * 1(正数)    按存进去的顺序 正序打印
     * -1(负数)   按存进去的顺序 倒序打印
     * 
     * TreeSet  按二叉树保存的
     * 要保存的数比我大   放在我的右边  (返回负数)
     * 要保存的数比我小   放在我的左边  (返回正数)
     * 要保存的数一样大   不储存
     * 打印按从小到大输出(升序)
class Worker extends Person implements Comparable<Worker>{
        public Worker() {
        super();
        // TODO Auto-generated constructor stub
    }

    public Worker(String name, int age) {
        super(name, age);
        // TODO Auto-generated constructor stub
    }
    @Override
    public int compareTo(Worker o){
        //  按年龄比较
        return this.getAge() - o.getAge();
    }

    @Override
    public int compareTo(Worker o){
        //  按姓名比较
        return this.getName().compareTo(o.getName());
    }
    @Override
    public int compareTo(Worker o){
        //  不去重
        //  比较的主要条件 按年龄
        //  次要条件       按姓名
        int num = this.getAge() - o.getAge();
        return num == 0 ? this.getName().compareTo(o.getName()) : num;
    }
    @Override
    public int compareTo(Worker o){
        // 主要比字符串长度
        // 然后比年龄
        // 最后比较字符串

        int length = this.getName().length() - o.getName().length();
        int num = length == 0 ? (this.getAge() - o.getAge()) : length;
        return num == 0 ? this.getName().compareTo(o.getName()) : num;
    }
}
public static void fun2(){
    TreeSet<Worker> set = new TreeSet<Worker>();
    set.add(new Worker("张三",15));
    set.add(new Worker("李四",16));
    set.add(new Worker("王五",14));
    set.add(new Worker("赵六",17));

    //输出方式一:
    Susyem.out.println(set);
    //输出方式二:
    for(Worker work : set){
        System.out.println(work);
    }
}
比较器
创建比较器来排序
1.创建一个类 实现Comparator接口
2.实现接口中的方法 并 编写 比较的规则
3.把该类的对象 存入TreeSet集合中
示例1
//  保留重复的字符串
//  按字符串长度排序

public static void fun3(){
    TreeSet<String> set = new TreeSet<>(new keepString());
    set.add("asd");
    set.add("wq");
    set.add("jjjj");
    set.add("qwe");
    set.add("a");
    System.out.println(set);   //结果:按长度升序排列
}

//实现Comparator接口中compare方法
class keepString implements Comparator<String>{
    //  比较的规则
    //  主要比较字符串长度
    //  次要比字符串
    @Override
    public int compare(String o1, String o2){
        int num = o1.length() - o2.length();
        return num == 0 ? o1.compareTo(o2) : num;
    }
}
示例2
  键盘接收一个字符串, 程序对其中所有字符进行排序
  要求保留重复的  使用比较器

public static void fun4(){
    Scanner sc = new Scanner(System.in);
    System.out.println("请输入一个字符串:");
    String str = scanner.nextLine();
    TreeSet<Character> set = new TreeSet<>(new keepCharracter());
    for(int i = 0; i < str.length(); i++){
        set.add(str.charAt(i));
    }
    System.out.println(set);
}  

class keepCharracter implements  comparator<Chararcter>{
    @Override
    public int compare(Character o1, Character o2){
        return o1 > o2 ? 1 : -1;
    }
}
示例3
从键盘输入几个整数 进行排序  输入"quit"停止输入
public static void fun5(){
    TreeSet<Integer> set = new TreeSet<Integer>(new keepInteger());
    Scanner sc = new Scanner(System.in);
    System.out.println("请输入:");
    String str = sc.nextLine();
    while(!"quit".equals(str)){
        int integer = Integer.parse(str);
        set.add(integer);
        System.out.println("请输入:");
        str = scanner.nextLine();
    }
    System.out.println(set);
}

class keepInteger implements Comparator<Integer>{
    @Override
    public int compare(Integer o1, Integer o2){
        int num = o1 - o2;
        return num == 0 ? 1 : num;
    }
}
示例4
public class Student implements Comparable<Stdudent>{
    private String name;
    private int chinese;
    private int math;
    private int english;
    private int sum;
    public Student1() {
        super();
        // TODO Auto-generated constructor stub
    }
    public Student1(String name, int chinese, int math, int english) {
        super();
        this.name = name;
        this.chinese = chinese;
        this.math = math;
        this.english = english;
        sum = chinese + math + english;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getChinese() {
        return chinese;
    }
    public void setChinese(int chinese) {
        this.chinese = chinese;
    }
    public int getMath() {
        return math;
    }
    public void setMath(int math) {
        this.math = math;
    }
    public int getEnglish() {
        return english;
    }
    public void setEnglish(int english) {
        this.english = english;
    }
    public int getSum() {
        return sum;
    }


    @Override
    public String toString() {
        return "Student1 [name=" + name + ", chinese=" + chinese + ", math=" + math + ", english=" + english + ", sum="
                + sum + "]";
    }

    @Override
    public int compareTo(Student o){
        int num = this.num - o.sum;
        return num == 0 ? 1 : num;
    }

}

public static void main(String[] args){
    TreeSet< Student> set = new TreeSet<>();
    Scanner scanner = new Scanner(System.in);
    // 循环输入5个学生
        while(set.size() < 5) {
            System.out.println("录入的学生信息格式(姓名,语文成绩,数学成绩,英语成绩)");
            //  王龙,150,150,150
            String string = scanner.nextLine();
            //  按逗号切割字符串 
            String[] strings = string.split(",");
            //  把成绩取出来
            int chinese = Integer.parseInt(strings[1]);
            int math = Integer.parseInt(strings[2]);
            int english = Integer.parseInt(strings[3]);

            //  构建对象
            Student1 student = new Student1(strings[0], chinese, math, english);
            //  把对象扔集合中
            set.add(student);
        }
        //  打印一下
        System.out.println(set);
}
示例5
public static void main(String[] args) {
        //  键盘录入5个学生信息(姓名,语文成绩,数学成绩,英语成绩)
        //  录入的学生信息格式(姓名,语文成绩,数学成绩,英语成绩)
        //  王龙,150,150,150
        //  按照总分从高到低输出到控制台。输出学生所有信息
        TreeSet< Student> set = new TreeSet<>(new KeepStudent());
        Scanner scanner = new Scanner(System.in);
        for(int i = 0; i < 5; i++) {
            Student student = new Student();
            System.out.println("请输入 姓名,语文成绩,数学成绩,英语成绩");
            String string = scanner.nextLine();
            String[] split = string.split(",");

            student.setName(split[0]);

            Integer integer3 = Integer.parseInt(split[1]);
            student.setGrade1(integer3);

            Integer integer1 = Integer.parseInt(split[2]);
            student.setGrade2(integer1);

            Integer integer2 = Integer.parseInt(split[3]);
            student.setGrade3(integer2);

            set.add(student);
        }
        System.out.println(set);
}
class keepStudent implements Comparator<Student>{
    @Override
    public int compare(Student o1, Student o2) {
        // TODO Auto-generated method stub

        int num1= o1.getGrade1() + o1.getGrade2() + o1.getGrade3();
        int num2 = o2.getGrade1() + o2.getGrade2() + o2.getGrade3(); 
        int num = num1 - num2;
        if(num == 0) {
            return 1;
        }
        return num;
    }


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值