zoukankan      html  css  js  c++  java
  • java集合类-Set接口

    Set集合

    Set集合中的对象不按特定的方式排序,只是简单的把对象放入集合中,但是不能包含重复对象。

    Set集合由Set接口和Set接口的实现类组成,Set接口继承与于Collection接口

     

    Set接口的实现类

    Set接口常用的实现类有HashSet类和TreeSet类

    • HashSet类实现Set接口,底层实现是哈希表(HashMap)实现的,它不保证Set的迭代顺序,线程不安全,存取速度快
      • LinkedHashSet父类是HashSet,存取有序,元素不能重复
    • TreeSet类不仅实现了Set接口,还实现了SortedSet接口,因此,TreeSet类实现的Set集合在遍历结合时按照自然顺序递增排序,也可以按照指定比较器递增排序

    HashSet

     

    哈希表里存放的是哈希值,HashSet存储元素是按照哈希值来存的所以取数据也是按照哈希值取得。

    HashSet底层实际上是个HashMap

     

    AbstractCollection->AbstractSet->HashSet

     

       public HashSet() {
    
            map = new HashMap<>();
    
        }
    

      

    哈希表又叫做散列表,哈希表底层是一个数组,这个数组中每一个元素是一个单向链表,每个单向链表都有一个独一无二的hash值,代表数组的下标。在某个单向链表中的每一个节点上的hash值是相同的。hash值实际上是key调用hashCode方法,再通过"hash function"转换成的值

     

    HashSet常用方法和底层实现

     

        // 添加元素,调用的map的put方法
    
        public boolean add(E e) {
    
            return map.put(e, PRESENT)==null;
    
        }
    
        // 删除元素,调用map的remove方法
    
        public boolean remove(Object o) {
    
            return map.remove(o)==PRESENT;
    
        }
    
        // 判断元素是否存在
    
        public boolean contains(Object o) {
    
            return map.containsKey(o);
    
        }
    
        // 判断set是否为空 
    
        public boolean isEmpty() {
    
            return map.isEmpty();
    
        }
    

      

    TreeSet

     

    TreeSet的底层实现是TreeMap,TreeSet会自动排序,里面的元素都是有序的,根据存储元素实现的Comparable接口,重写compareTo方法来进行排序。当TreeSet的泛型对象不是java的基本类型的包装类时,对象需要重写Comparable#compareTo()方法

     

    AbstractCollection->AbstractSet->TreeSet

     

        TreeSet treeSet = new TreeSet();
    
        treeSet.add(10);
    
        treeSet.add(50);
    
        treeSet.add(30);
    
        System.out.println("tree set: "+treeSet);
    
        // 输出 【10,30,50】
    

      

    如果保存是自定义的类,只要实现Comparable接口就能排序

     class Person implements Comparable {
    
            String name;
            int age;
            public Person(String name, int age) {
                this.name = name;
                this.age = age;
            }
    
     
    
            @Override
            public int compareTo(Object o) {
                return this.age - ((Person) o).age;
            }
        }
    
        TreeSet treeSet = new TreeSet();
        treeSet.add(new Person("张三", 12));
        treeSet.add(new Person("李四", 45));
        treeSet.add(new Person("王五", 32));
    Object p = treeSet.last(); System.out.println("tree set last: " + ((Person) p).name); // 得到的最后一个元素是年龄最大的

      

    1. 如果将compareTo()返回值写死为0,元素值每次比较,都认为是相同的元素,这时就不再向TreeSet中插入除第一个外的新元素。所以TreeSet中就只存在插入的第一个元素。
    2. 如果将compareTo()返回值写死为1,元素值每次比较,都认为新插入的元素比上一个元素大,于是二叉树存储时,会存在根的右侧,读取时就是正序排列的。
    3. 如果将compareTo()返回值写死为-1,元素值每次比较,都认为新插入的元素比上一个元素小,于是二叉树存储时,会存在根的左侧,读取时就是倒序序排列的。

    TreeSet的常用方法

     

    //返回set中第一个元素
    
        public E first() {
    
            return m.firstKey();
    
        }
    
        //返回set中最后一个元素
    
        public E last() {
    
            return m.lastKey();
    
        }
    
        //返回小于指定元素的最大的那个元素
    
        public E lower(E e) {
    
            return m.lowerKey(e);
    
        }
    
        //返回大于指定元素最小的那个元素
    
        public E higher(E e) {
    
            return m.higherKey(e);
    
       }

    总结

    HashSet与TreeSet的区别

    1、HashSet与TreeSet接口的一点不同,HashSet 保存的数据是无序的,TreeSet保存的数据是有序的,所以如果要想保存的数据有序应该使用TreeSet子类。

    2、利用TreeSet保存自定义类对象的时候,自定义所在的类一定要实现Comparable接口,如果没有实现这个接口那么就无法区分大小关系,而且在TreeSet中如果要进行排序,那么就要将所有的字段都进行比较,就是说在TreeSet中是依靠comparato()方法返回的是不是0来判断是不是重复元素的。

    3、如果是HashSet子类,那么其判断重复数据的方式不是依靠的comparable接口而是Object类之中的两个方法:(1)取得对象的哈希码 hashCode();(2)对象比较:equals(); 这俩个方法均不需要自己编写,在eclipse里面可以使用右键source 选择自动生成。就像生成Getter 和Setter 方法一样。

    最后:

    TreeSet 依靠的是Comparable 来区分重复数据;

    HashSet 依靠的是hashCode()、equals()来区分重复数据

    Set 里面不允许保存重复数据。

  • 相关阅读:
    Linux基础之文件管理(高级)上等相关内容-96
    Linux基础之文件管理(基础)等相关内容-95
    Linux基础之初识shell之系统命令基础等相关内容-94
    Linux基础之操作系统启动流程等相关内容-93
    人常犯的三种愚蠢
    数据挖掘科学家
    记住
    但行好事,莫问前程
    记住发生在身上的事,不要小心眼--活的明白
    语言要简洁
  • 原文地址:https://www.cnblogs.com/dreamyu/p/12019097.html
Copyright © 2011-2022 走看看