ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

java集合类-Set接口

2019-12-10 20:50:41  阅读:226  来源: 互联网

标签:Set java HashSet 元素 接口 public TreeSet


<style></style>

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 里面不允许保存重复数据。

标签:Set,java,HashSet,元素,接口,public,TreeSet
来源: https://www.cnblogs.com/dreamyu/p/12019097.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有