美文网首页Java学习笔记
9.7-全栈Java笔记:Set接口和实现类

9.7-全栈Java笔记:Set接口和实现类

作者: 全栈JAVA笔记 | 来源:发表于2017-07-04 10:10 被阅读125次

    Set接口

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

      

    Set容器表示:无序、不可重复。无序表示Set中的元素没有索引,我们只能遍历查找;不可重复表示:不允许加入重复的元素。更确切地讲,新元素如果和Set中某个元素通过equals()方法比对为true,则不能加入;甚至,Set中也只能放入一个null元素,不能多个。

     

    Set常用的实现类有:HashSet、TreeSet等,我们一般使用HashSet。

    HashSet基本使用

    大家在做下面练习时,重点体会“Set是无序、不可重复”的核心要点。 

    【示例1HashSet的使用

    public class   TestSet01 {

        public static void   main(String[] args) {

           Set<String> s = new   HashSet<String>();

           s.add ("hello");

           s.add ("world");

           System.out.println(s);

           s.add ("hello"); //   相同的元素不会被加入

           System.out.println   (s);

           s.add(null);

           System.out.println(s);

           s.add(null);

           System.out.println(s);

        }

    }

    示例1 运行效果图

    HashSet底层实现

    HashSet是采用哈希算法实现,底层实际是用HashMap实现的(HashSet本质就是一个简化版的HashMap),因此,查询效率和增删效率都比较高。 

    我们打开JDK中HashSet的源码:

    public class   HashSet<E>  implements   Set<E>, Cloneable, java.io.Serializable {

        private transient   HashMap<E, Object> map;

        private static final   Object PRESENT = new   Object();

        public   HashSet() {

           map = new   HashMap<E, Object>();

        }

        public boolean   add(E e) {

           return map.put(e,   PRESENT) == null;

        }

        //多余代码,省略

    }

    我们发现里面有个map属性,这就是HashSet的核心秘密。我们再看add()方法,发现增加一个元素说白了就是在map中增加一个键值对,键对象就是这个元素,值对象是名为PRESENT的Object对象。说白了,就是“往set中加入元素,本质就是把这个元素作为key加入到了内部的map中”。

    由于map中key都是不可重复的,因此,Set天然具有“不可重复”的特性。

    TreeSet的使用和底层实现

    TreeSet底层实际是用TreeMap实现的,内部维持了一个简化版的TreeMap,通过key来存储Set的元素。 TreeSet内部需要对存储的元素进行排序,因此,我们对应的类需要实现Comparable接口。这样,才能根据compareTo()方法比较对象之间的大小,才能进行内部排序。

    【示例2】 TreeSet和Comparable接口使用

    public class   Test {

        public static void   main(String[] args) {

           User u1 = new   User(1001,"高淇",18);

           User u2 = new   User(2001,"高希希",5);

           Set<User> set = new   TreeSet<User>();

           set.add(u1);

           set.add(u2);

        }

    }

    class   User implements Comparable<User>{

        int id;

        String uname;

        int age;

        public   User(int id, String uname,int   age) {

           this.id =   id;

           this.uname =   uname;

           this.age =   age;

        }

        /**

         *  返回0   表示 this == obj

           返回正数表示   this  >  obj

           返回负数表示   this  <  obj

         */

        @Override

        public int   compareTo(User o) {

           if(this.id>o.id){

               return 1;

           }else if(this.id<o.id){

               return   -1;

           }else {

               return 0;

           }

        }

    }

    使用TreeSet要点:

    1. 由于是二叉树,需要对元素做内部排序。 如果要放入TreeSet中的类没有实现Comparable接口,则会抛出异常:java.lang.ClassCastException

    2.  TreeSet中不能放入null元素


    「全栈Java笔记」是一部能帮大家从零到一成长为全栈Java工程师系列笔记。笔者江湖人称 Mr. G,10年Java研发经验,曾在神州数码、航天院某所研发中心从事软件设计及研发工作,从小白逐渐做到工程师、高级工程师、架构师。精通Java平台软件开发,精通JAVAEE,熟悉各种流行开发框架。

      笔记包含从浅入深的六大部分:

      A-Java入门阶段

      B-数据库从入门到精通

      C-手刃移动前端和Web前端

      D-J2EE从了解到实战

      E-Java高级框架精解

      F-Linux和Hadoop 

    相关文章

      网友评论

        本文标题:9.7-全栈Java笔记:Set接口和实现类

        本文链接:https://www.haomeiwen.com/subject/wbpthxtx.html