Bootstrap

只讲干货!!该努力了吧?该上进了吧?今天拿下:set类容器!

set类容器

Set接口介绍

        Set接口继承自 Collection 接口, Set 接口中没有新增方法,它和Collection接口保持完全一致。我们在前面学习 List 接口的使用方式,在Set 中仍然适用。因此,学习 Set 的使用将没有任何难度。

Set接口特点

        Set特点: 无序、不可重复 。无序指 Set 中的元素没有索引,我们只能遍历查找;不可重复指不允许加入重复的元素。更确切地讲,新元素如果和Set 中某个元素通过 equals() 方法对比为 true ,则只能保留一个。
        Set常用的实现类有: HashSet TreeSet 等,我们一般使用HashSet。

HashSet容器的使用

        HashSet是 Set 接口的实现类。是 Set 存储特征的具体实现。
public class HashSetTest {
   public static void main(String[] args) {
       //实例化HashSet
       Set<String> set = new HashSet<>();
       //添加元素
       set.add("a");
       set.add("b1");
       set.add("c2");
       set.add("d");
       set.add("a");
       //获取元素,在Set容器中没有索引,所以没有对应的get(int index)方法
       for(String str: set){
           System.out.println(str);
      }
       System.out.println("--------------------");
       //删除元素
       boolean flag = set.remove("c2");
       System.out.println(flag);
       for(String str: set){
           System.out.println(str);
      }
       System.out.println("------------------------");
       int size = set.size();
       System.out.println(size);
  }
}

HashSet存储特征分析

        HashSet 是一个不保证元素的顺序且没有重复元素的集合,是线程不安全的。HashSet 允许有 null 元素。

无序

        在HashSet 中底层是使用 HashMap 存储元素的。 HashMap 底层使用的是数组与链表实现元素的存储。元素在数组中存放时,并不是有序存放的也不是随机存放的,而是对元素的哈希值进行运算决定元素在数组中的位置。

不重复

        当两个元素的哈希值进行运算后得到相同的在数组中的位置时,会调用元素的equals()方法判断两个元素是否相同。如果元素相同则不会添加该元素,如果不相同则会使用单向链表保存该元素。

通过HashSet存储自定义对象

创建Users对象

public class Users {
    private String username;
    private int userage;
    public Users(String username, intuserage) {
        this.username = username;
        this.userage = userage;
   }

    public Users() {
   }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() !=o.getClass()) return false;

        Users users = (Users) o;

        if (userage != users.userage) returnfalse;
        return username != null ?username.equals(users.username) :
        users.username == null;
   }

    @Override
    public int hashCode() {
        int result = username != null ?username.hashCode() : 0;
        result = 31 * result + userage;
        return result;
   }

    public String getUsername() {
        return username;

   }

    public void setUsername(String username){
        this.username = username;
   }

    public int getUserage() {
        return userage;
   }

    public void setUserage(int userage) {
        this.userage = userage;
   }

    @Override
    public String toString() {
        return "Users{" +
                "username='" + username +'\'' +
                ", userage=" + userage +
                '}';
   }
 }

HashSet中存储Users对象

public class HashSetTest2 {
    public static void main(String[] args) {
       //实例化HashSet
        Set<Users> set = new HashSet<>();
        Users u = new Users("秃头",18);
        Users u1 = new Users("秃头",18);
        set.add(u);
        set.add(u1);
        System.out.println(u.hashCode());
        System.out.println(u1.hashCode());
        for(Users users:set){
            System.out.println(users);
       }
   }
}

TreeSet容器的使用

        TreeSet实现了 Set 接口,它是一个可以对元素进行排序的容器。底层实际是用TreeMap 实现的,内部维持了一个简化版的 TreeMap ,通过key 来存储元素。 TreeSet 内部需要对存储的元素进行排序,因此,我们需要给定排序规则。
排序规则实现方式:
                通过元素自身实现比较规则。
                通过比较器指定比较规则。
 public class TreeSetTest {
    public static void main(String[] args) {
        //实例化TreeSet
        Set<String> set = new TreeSet<>();
        //添加元素
        set.add("c");
        set.add("a");
        set.add("d");
        set.add("b");
        set.add("a");

        //获取元素
        for(String str :set){
            System.out.println(str);
       }
   }
}

通过元素自身实现比较规则

        在元素自身实现比较规则时,需要实现Comparable 接口中的compareTo方法,该方法中用来定义比较规则。 TreeSet 通过调用该方法来完成对元素的排序处理。

创建Users

public class Users implements Comparable<Users>{
    private String username;
    private int userage;

    public Users(String username, int userage) {
        this.username = username;
        this.userage = userage;
   }


    public Users() {
   }

    @Override
    public boolean equals(Object o) {
        System.out.println("equals...");
        if (this == o) return true;
        if (o == null || getClass() !=o.getClass()) return false;

        Users users = (Users) o;

        if (userage != users.userage) return false;
        return username != null ?username.equals(users.username) :users.username == null;
   }

    @Override
    public int hashCode() {
        int result = username != null ?username.hashCode() : 0;
        result = 31 * result + userage;
        return result;
   }

    public String getUsername() {
        return username;
   }


    public void setUsername(String username){
        this.username = username;
   }

    public int getUserage() {
        return userage;
   }

    public void setUserage(int userage) {
        this.userage = userage;
   }

    @Override
    public String toString() {
        return "Users{" +
                "username='" + username +'\'' +
                ", userage=" + userage +
                '}';
   }

    //定义比较规则
    //正数:大,负数:小,0:相等
    @Override
    public int compareTo(Users o) {
        if(this.userage > o.getUserage()){
            return 1;
       }
        if(this.userage == o.getUserage()){
           return this.username.compareTo(o.getUsername());

       }
        return -1;
   }
 }
 Set<Users> set1 = new TreeSet<>();
 Users u = new Users("秃头",18);
 Users u1 = new Users("小子",22);
 Users u2 = new Users("TUT",22);
 set1.add(u);
 set1.add(u1);
 set1.add(u2);
 for(Users users:set1){
    System.out.println(users);
 }

通过比较器实现比较规则

        通过比较器定义比较规则时,我们需要单独创建一个比较器,比较器需要实现Comparator接口中的 compare 方法来定义比较规则。在实例化TreeSet 时将比较器对象交给 TreeSet 来完成元素的排序处理。此时元素自身就不需要实现比较规则了。

创建Student

public class Student {
    private String name;
    private int age;
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
   }
    public Student() {
   }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", 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 boolean equals(Object o) {
       if (this == o) return true;
      if (o == null || getClass() !=o.getClass()) return false;

       Student student = (Student) o;

       if (age != student.age) return false;
        return name != null ? name.equals(student.name) : student.name == null;
   }

    @Override
    public int hashCode() {
        int result = name != null ?name.hashCode() : 0;
        result = 31 * result + age;
        return result;
   }
 }

创建比较器

public class StudentComparator implements
Comparator<Student> {

    //定义比较规则
    @Override

    public int compare(Student o1, Student o2) {
        if(o1.getAge() > o2.getAge()){
            return 1;
       }
        if(o1.getAge() == o2.getAge()){
            return o1.getName().compareTo(o2.getName());
       }
        return -1;
   }
 }
 public class TreeSetTest3 {
    public static void main(String[] args) {
        //创建TreeSet容器,并给定比较器对象
        Set<Student> set = new TreeSet<>(new StudentComparator());
        Student s = new Student("秃头",18);
        Student s1 = new Student("小子",22);
        Student s2 = new Student("TUT",22);
        set.add(s);
        set.add(s1);
        set.add(s2);
        for(Student student:set){
            System.out.println(student);
       }
   }
 }

单例集合使用案例

需求:
        产生1-10 之间的随机数 ([1,10] 闭区间 ) ,将不重复的 10 个随机数放到容器中。

使用List类型容器实现

public class ListDemo {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
       while(true){
           //产生随机数
           int num = (int)(Math.random()*10+1);
            //判断当前元素在容器中是否存在
           if(!list.contains(num)){
                list.add(num);
           }
           //结束循环
           if(list.size() == 10){
               break;
           }
       }
       for(Integer i:list){
           System.out.println(i);
       }
   }
}

使用Set类型容器实现

public class SetDemo {
    public static void main(String[] args) {
        Set<Integer> set = new HashSet<>();
        while(true){
            int num = (int)(Math.random()*10+1);
            //将元素添加容器中,由于Set类型容器是不允许有重复元素的,所以不需要判断。
            set.add(num);
            //结束循环
            if(set.size() == 10){
                break;
           }
       }
        for(Integer i:set){
            System.out.println(i);
       }
   }
}

只讲干货

#有什么错误的地方大家多多担待,欢迎大家留下意见共同努力。


#需要什么技术的内容大家也可以积极留言。


#有升本的伙伴也可留言,后序也可更新升本内容C 和数据结构。


#有需要的伙伴或有什么问题直接联留下wx或联系邮箱2821835676qq.com

;