Bootstrap

Java中的Set集合

一、概述

Set集合是Collection集合的子体系,它的元素特点是无序、唯一

  • Set集合是一个接口,所以不能通过new的方式直接创建它的对象
  • Set集合中没有带索引的方法,所以不能通过普通for循环遍历
  • Set集合的常用子类主要有两个,分别是HashSet集合和TreeSet集合

二、哈希值

  • 概述

    • 所谓的哈希值指的是JDK根据对象的地址,或者字符串,或者数字算出来int类型的数字
  • 如何获取哈希值

    • 可以通过Object#hashCode()方法,获取指定对象的哈希值

      public int hashCode();	//根据对象,获取其对应的哈希值
      
      /**
       * 定义学生类,属性为姓名和年龄
       * 在测试类的main方法中,创建两个学生对象,分别获取他们的哈希值,并打印
       * 测试:重写Object#hashCode()方法,实现不同对象的哈希值也是相同的
       * 测试:同一对象哈希值肯定相同,不同对象哈希值一般不同
       */
      public class Student {
          String name;
          int age;
          public Student(String name, int age){
              this.name = name;
              this.age = age;
          }
          @Override
          public int hashCode(){
              return 666;
          }
      }
      
      
      class StudentTest{
          public static void main(String[] args) {
              Student s1 = new Student("EuropeanSheik",21);
              Student s2 = new Student("欧洲酋长",22);
              System.out.println(s1.hashCode());
              System.out.println(s2.hashCode());
              System.out.println(s2.hashCode());
          }
      }
      
    • 结论

      • 同一个对象多次调用hashCode()方法,返回的哈希值是相同的
      • 默认情况下不同对象的哈希值是不同的,但是通过方法重写,可以实现不同对象的哈希值是相同的
      • 同一对象哈希值肯定相同,不同对象哈希一般不同

三、HashSet集合

  • 特点

    • 底层数据结构是哈希表
    • 对集合的迭代顺序不做任何保证,也就是说,不保证元素的存取顺序一致
    • 没有带索引的方法,所以不能通过普通for循环遍历
    • 由于是Set集合,所以是不包含重复元素的集合
  • 总结

    • HashSet集合的特点是:无序、唯一、元素无索引,它的底层数据结构是:哈希表

      /**
       * 定义HashSet集合,存储字符串"hello","world","java","world"
       * 遍历HashSet集合,打印每一个元素值,并观察程序的运行结果
       */
      public class Test {
          public static void main(String[] args) {
              HashSet<String> set = new HashSet<String>();
              set.add("hello");
              set.add("world");
              set.add("java");
              set.add("world");
              Iterator it = set.iterator();
              while(it.hasNext()){
                  System.out.println(it.next());
              }
          }
      }
      

四、常见数据结构之哈希表

  • JDK8之前,底层采用数组+链表的形式实现,可以理解为:一个元素为链表的数组

  • JDK8以后,在长度比较长的时候,底层实现了优化

    /**
     * 定义学生类,属性为姓名和年龄
     * 创建HashSet集合,用来存储学生对象,并往其中添加3个学生的信息
     * 遍历集合,并把结果打印到控制台上
     * 如果学生对象的各个属性值都相同,我们就认为它们是同一个对象
     */
    public class Student{
        String name;
        int age;
        public Student(String name,int age){
            this.name = name;
            this.age = age;
        }
    }
    
    class StudentTest{
        public static void main(String[] args) {
            HashSet<Student> set = new HashSet<Student>();
            set.add(new Student("European",21));
            set.add(new Student("Sheik",22));
            set.add(new Student("欧洲酋长",23));
            for (Student s:set){
                System.out.println(s.name+s.age);
            }
        }
    }
    

;