Java基础(Set集合)

一、概述

Set 具有与 Collection 完全一样的接口,只是行为上不同,Set 不保存重复的元素,而且Set接口中元素无序。

本节需要了解的知识点:

什么是哈希表呢?

哈希表底层使用的也是数组机制,数组中存放对象,这些对象存放的位置比较特殊,当把这些对象存入数组中时,会根据这些对象的特有数据结合相应的算法(hashCode),计算出这个对象在数组中的位置,然后把这个对象存放在数组中。而这样的数组就称为哈希数组,即就是哈希表。

当向哈希表中存放元素时,会调用Object类中的hashCode方法。由于任何对象都是Object类的子类,所以任何对象有拥有这个方法。这里需要注意,如果两个对象hashCode方法算出结果一样,这样现象称为哈希冲突,这时会调用对象的equals方法,比较这两个对象是不是同一个对象,如果equals方法返回的是true,那么就不会把第二个对象存放在哈希表中,如果返回的是false,就会把这个值存放在哈希表中。

保证Set集合元素的唯一,其实就是根据对象的hashCode和equals方法来决定的。如果我们往集合中存放自定义的对象,那么保证其唯一,就必须复写hashCode和equals方法建立属于当前对象的比较方式。

示例:set和list的比较

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class demo_set无序 {
    public static void main(String[] args) {
        List<String> list=new ArrayList<>();
        list.add("aaa");
        list.add("ccc");
        list.add("aaa");
        list.add("bbb");
        //不保存重复的元素且无序
        Set set=new HashSet();
        set.add("ccc");
        set.add("aaa");
        set.add("bbb");
        set.add("aaa");
        System.out.println(list);
        System.out.println(set);
    }
}

运行结果:

二、HashSet存储自定义对象

当使用HashSet存储自定义对象时,我们要重写hashCode()和equals()方法

因为:

       当调用HashSet的add()方法,会先判断hashCode()是否相同,

       如果相同,就会再判断equals(),如果equals()也相同,那么就不存。

比如班上有两个人姓名和年龄都相同,但是必须要把这两个人都存起来。

示例:

import java.util.HashSet;

public class demo_set添加对象 {
    public static void main(String[] args) {
        HashSet<Student> hashSet=new HashSet<>();
        hashSet.add(new Student("yyy",21));
        hashSet.add((new Student("wtc",21)));
        //添加重复元素
        hashSet.add((new Student("wtc",21)));
        System.out.println(hashSet);
    }
}
class Student{
    String name;
    int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
        return super.equals(o);
    }

    @Override
    public int hashCode() {
        return this.name.hashCode()+age;
    }

    @Override
    public String toString() {
        return "姓名:" + name  +
                " 年龄:" + age;
    }
}

运行结果:

三、练习题

           1.获取10个不重复的1-20之间的随机数

import java.util.HashSet;
import java.util.Random;

public class demo_获取10个不重复随机数 {
    public static void main(String[] args) {
        HashSet hashSet=new HashSet();
        Random r=new Random();
        while(hashSet.size()<10){
            //范围1-20
            int i=r.nextInt(20)+1;
            hashSet.add(i);
        }
        System.out.println(hashSet);
    }
}

运行结果:

 四、TreeSet接口

特点:1.元素是有序的
           2.不能存储重复的元素

存储自定义对象:  需要告诉它应该按照什么来排序 

                               需要实现接口:Compareble

                               实现接口的抽象方法:compareTo  

                                         在它里面去编写排序的规则

                                            compareTo里面可以返回三种值

                                            * 1.大于0 * 2.小于0 * 3.等于0 * 

示例:

import java.util.TreeSet;

public class demo_TreeSet {
    public static void main(String[] args) {
        TreeSet treeSet=new TreeSet();
        treeSet.add("aaa");
        treeSet.add("ddd");
        treeSet.add("bbb");
        treeSet.add("ccc");
        treeSet.add("aaa");
        System.out.println(treeSet);

        TreeSet<Students> treeSet1=new TreeSet<>();
        treeSet1.add(new Students("yyy",20));
        treeSet1.add(new Students("wtc",23));
        treeSet1.add(new Students("wt",22));
        treeSet1.add(new Students("wtc",20));

        System.out.println(treeSet1);
    }
}
class Students implements Comparable<Students>{
    String name;
    int age;

    public Students(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public int compareTo(Students o) {
        //解决年龄相同的问题,按年龄排序
        int i=this.age-o.age;
        return i==0?this.name.compareTo(o.name):i;
    }

    @Override
    public String toString() {
        return "Students{" +
                "姓名:" + name +
                " 年龄:" + age +
                '}';
    }
}

运行结果:

五、通过构造方法传入排序比较器

解决问题:不能在对象类内进行改动去实现接口

示例:


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

public class demo_构造方法传入比较器 {
    public static void main(String[] args) {
        //第一种写法
        Comparator comparator=new Comparator<Person>(){
            @Override
            public int compare(Person o1, Person o2) {
                //实现按年龄排序
                int i=o1.age-o2.age;
                return i==0?o1.name.compareTo(o2.name):i;
            }
        };
        TreeSet<Person> treeSet=new TreeSet<>(comparator);

        /**第二种写法
         *         TreeSet<Person> treeSet=new TreeSet<>(ew Comparator<Person>(){
         *             @Override
         *             public int compare(Person o1, Person o2) {
         *                 //实现按年龄排序
         *                 int i=o1.age-o2.age;
         *                 return i==0?o1.name.compareTo(o2.name):i;
         *             }
         *         });
         */

        treeSet.add(new Person("YYY",18));
        treeSet.add(new Person("wtc",21));
        treeSet.add(new Person("wt1",21));

        System.out.println(treeSet);
    }
}
class Person{
    String name;
    int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "姓名:" + name + '\'' +
                " 年龄:" + age +
                '}';
    }
}

运行结果:

 

 

发布了75 篇原创文章 · 获赞 164 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/qq_41679818/article/details/96729011