• 【Java】Collection子接口:其二 Set 组接口


    Collection子接口:其二 Set 组接口 

    - Set接口是Collection的子接口,Set没有提供额外的方法

    - Set集合中不允许包含重复的元素,如果重复添加,只保留最新添加的那一个

    - Set判断两个元素是否相同不是 == 判断,而是取equals()方法

    Set主要实现类:

    HashSet、LinkedHashSet、TreeSet

    - HashSet  Set主要接口实现类、线程不安全的、可存储Null值

    - LinkedHashSet  继承了HashSet、遍历内部数据,可按照添加时的顺序遍历

    - TreeSet  底层存储结构是红黑树【二叉树】,按照指定属性进行排序

    Set底层的说明,红康老师讲的还是不解,决定留在数据结构篇再来细谈

    https://www.bilibili.com/video/BV1Kb411W75N?p=537

    底层算法的哈希码

    https://www.cnblogs.com/mindzone/p/12736516.html

     1 public class CollectionTest {
     2     public static void main(String[] args) {
     3         Set set = new HashSet();
     4 
     5         set.add("阿伟");
     6         set.add("杰哥");
     7         set.add("1376");
     8         set.add("先辈");
     9         set.add("Van");
    10         set.add("佟大为");
    11         set.add("1376");
    12         set.add(new Student("小明",12));
    13         set.add(new Student("小明",12));
    14 
    15         Iterator iterator = set.iterator();
    16 
    17         while(iterator.hasNext()){
    18             Object next = iterator.next();
    19             System.out.println(next);
    20         }
    21         //  阿伟  Van  1376   佟大为   杰哥  先辈
    22         //  无序性不是遍历的结果没有顺序(不是随机性) 存储的数据不是按照索引顺序排列的,根据数据的Hash值添加
    23         //  不可重复性 这里添加了同一字符串1376,从哈希码可以判断是一样,set集合只会保留其中一个
    24 
    25         //  如果是对象就不一样了,这里依然会保留两个同属性对象,底层哈希码是不一样的
    26         //  再重写equals & hashCode 之后只保留一个对象了, 调用add方法时,set会调用对象的equals方法判断,为true将不会添加
    27     }
    28 }
    29 
    30 
    31 class Student{
    32     private String name;
    33     private Integer age;
    34 
    35     public String getName() {
    36         return name;
    37     }
    38 
    39     public void setName(String name) {
    40         this.name = name;
    41     }
    42 
    43     public Student(String name, Integer age) {
    44         this.name = name;
    45         this.age = age;
    46     }
    47 
    48     public Integer getAge() {
    49         return age;
    50     }
    51 
    52     public void setAge(Integer age) {
    53         this.age = age;
    54     }
    55 
    56     @Override
    57     public String toString() {
    58         return "Student{" +
    59                 "name='" + name + '\'' +
    60                 ", age=" + age +
    61                 '}';
    62     }
    63 
    64     @Override
    65     public boolean equals(Object o) {
    66         if (this == o) return true;
    67         if (!(o instanceof Student)) return false;
    68         Student student = (Student) o;
    69         return Objects.equals(getName(), student.getName()) &&
    70                 Objects.equals(getAge(), student.getAge());
    71     }
    72 
    73     @Override
    74     public int hashCode() {
    75         return Objects.hash(getName(), getAge());
    76     }
    77 }

    LinkedHashSet,是HashSet的子类

    添加数据的同时每个数据维护了两个引用,记录前一个数据和后一个数据

    对于频繁的遍历操作,LinkedHashSet效率高于HashSet

    public class CollectionTest {
        public static void main(String[] args) {
            Set set = new LinkedHashSet();
    
            set.add("阿伟");
            set.add("杰哥");
            set.add("1376");
            set.add("先辈");
            set.add("Van");
            set.add("佟大为");
            set.add("1376");
    
            Iterator iterator = set.iterator();
    
            while(iterator.hasNext()){
                Object next = iterator.next();
                System.out.println(next);
            }
        }
    }

    TreeSet存储的数据只能是同一个类型的数据

    自定义数据类型或者其他的基本类型封装类

    TreeSet方式的判断是以Comparable接口实现的compareTo方法操作的【自然排序方式】

    0 表示相同 TreeSet将会认为是重复,不再添加重复的元素

     1 public class CollectionTest {
     2     public static void main(String[] args) {
     3         Set set = new TreeSet();
     4 
     5         set.add(new Person("Jimmy",17));
     6         set.add(new Person("Mike",13));
     7         set.add(new Person("Jim",15));
     8         set.add(new Person("Jack",12));
     9         set.add(new Person("Jerry",18));
    10         set.add(new Person("Jack",56));
    11 
    12         Iterator iterator = set.iterator();
    13 
    14         while(iterator.hasNext()){
    15             Object next = iterator.next();
    16             System.out.println(next);
    17         }
    18     }
    19 }
    20 
    21 
    22 // 需要实现Comparable接口
    23 class Person implements Comparable{
    24     private String name;
    25     private Integer age;
    26 
    27     public Person(String name, Integer age) {
    28         this.name = name;
    29         this.age = age;
    30     }
    31 
    32     public String getName() {
    33         return name;
    34     }
    35 
    36     public void setName(String name) {
    37         this.name = name;
    38     }
    39 
    40     public Integer getAge() {
    41         return age;
    42     }
    43 
    44     public void setAge(Integer age) {
    45         this.age = age;
    46     }
    47 
    48     @Override
    49     public String toString() {
    50         return "Person{" +
    51                 "name='" + name + '\'' +
    52                 ", age=" + age +
    53                 '}';
    54     }
    55 
    56     // 重写此方法
    57     @Override
    58     public int compareTo(Object o) {
    59         if (o instanceof Person){
    60             Person p = (Person)o;
    61             int compare = this.name.compareTo(p.name); // 掉用String的compareTo方法,不是本地的
    62             if (compare != 0) return compare;
    63             else return Integer.compare(this.age,p.age);    // 如果相同,再compare第二属性
    64         }else throw new RuntimeException("装入的类型不匹配!");
    65     }
    66 }

    详细红黑树可以参考自视频里面的这篇链接,作者博客已经搬迁了啊

    https://www.yycoding.xyz/post/2014/3/27/introduce-red-black-tree

    除了上面的自然排序,也支持定制排序

     1 public class CollectionTest {
     2     public static void main(String[] args) {
     3         Comparator comparator = new Comparator() {
     4             // 按照年龄从小到大排列,一样剔除
     5             @Override
     6             public int compare(Object o1, Object o2) {
     7                 if (o1 instanceof Person && o2 instanceof Person){
     8                     Person p1 = (Person)o1;
     9                     Person p2 = (Person)o2;
    10                     return Integer.compare(p1.getAge(),p2.getAge());
    11                 }else throw new RuntimeException("类型不匹配!");
    12             }
    13         };
    14 
    15         // 如果定义了定制排序,创建Set集合初始化时,注入定制比较器,TreeSet就会默认使用此比较
    16         Set set = new TreeSet(comparator);
    17 
    18         set.add(new Person("Jimmy",17));
    19         set.add(new Person("Mike",13));
    20         set.add(new Person("Jim",15));
    21         set.add(new Person("Jack",12));
    22         set.add(new Person("Jerry",18));
    23         set.add(new Person("Jack",56));
    24 
    25         Iterator iterator = set.iterator();
    26 
    27         while(iterator.hasNext()){
    28             Object next = iterator.next();
    29             System.out.println(next);
    30         }
    31     }
    32 }
    33 
    34 
    35 // 需要实现Comparable接口
    36 class Person implements Comparable{
    37     private String name;
    38     private Integer age;
    39 
    40     public Person(String name, Integer age) {
    41         this.name = name;
    42         this.age = age;
    43     }
    44 
    45     public String getName() {
    46         return name;
    47     }
    48 
    49     public void setName(String name) {
    50         this.name = name;
    51     }
    52 
    53     public Integer getAge() {
    54         return age;
    55     }
    56 
    57     public void setAge(Integer age) {
    58         this.age = age;
    59     }
    60 
    61     @Override
    62     public String toString() {
    63         return "Person{" +
    64                 "name='" + name + '\'' +
    65                 ", age=" + age +
    66                 '}';
    67     }
    68 
    69     // 重写此方法
    70     @Override
    71     public int compareTo(Object o) {
    72         if (o instanceof Person){
    73             Person p = (Person)o;
    74             int compare = this.name.compareTo(p.name); // 掉用String的compareTo方法,不是本地的
    75             if (compare != 0) return compare;
    76             else return Integer.compare(this.age,p.age);    // 如果相同,再compare第二属性
    77         }else throw new RuntimeException("装入的类型不匹配!");
    78     }
    79 }

    没有写定制排序才会按照equals方法排序

  • 相关阅读:
    (原)试问那些不劳而获的人?
    (原)资源互换原则
    (原)关于与人沟通时的几个中文语法
    osgviewer读取dxf文件,拣选高亮功能小结
    qt的OSG视图中拣选对象事件消息
    1)OSG与QT单文档视图的结合
    三维渲染引擎设计与实践(八)
    三维渲染引擎设计与实践(七)
    三维渲染引擎设计与实践(六)
    三维渲染引擎设计与实践(五)
  • 原文地址:https://www.cnblogs.com/mindzone/p/12742866.html
Copyright © 2020-2023  润新知