zoukankan      html  css  js  c++  java
  • 5.03_集合框架(set集合)

    一、Set集合概述

      一个不包含重复元素的 collection。更确切地讲,set 不包含满足 e1.equals(e2) 的元素对 e1e2,并且最多包含一个 null 元素。正如其名称所暗示的,此接口模仿了数学上的 set 抽象。

      在所有构造方法以及 addequalshashCode 方法的协定上,Set 接口还加入了其他规定,这些规定超出了从 Collection 接口所继承的内容。出于方便考虑,它还包括了其他继承方法的声明(这些声明的规范已经专门针对 Set 接口进行了修改,但是没有包含任何其他的规定)。

    对这些构造方法的其他规定是(不要奇怪),所有构造方法必须创建一个不包含重复元素的 set(正如上面所定义的)。

    注:如果将可变对象用作 set 元素,那么必须极其小心。如果对象是 set 中某个元素,以一种影响 equals 比较的方式改变对象的值,那么 set 的行为就是不确定的。此项禁止的一个特殊情况是不允许某个 set 包含其自身作为元素。

    某些 set 实现对其所包含的元素有所限制。例如,某些实现禁止 null 元素,而某些则对其元素的类型所有限制。试图添加不合格的元素会抛出未经检查的异常,通常是 NullPointerExceptionClassCastException。试图查询不合格的元素是否存在可能会抛出异常,也可能简单地返回 false;某些实现会采用前一种行为,而某些则采用后者。概括地说,试图对不合格元素执行操作时,如果完成该操作后不会导致在 set 中插入不合格的元素,则该操作可能抛出一个异常,也可能成功,这取决于实现的选择。此接口的规范中将这样的异常标记为“可选”。

    二、HashSet存储字符串并遍历  

        HashSet<String> hs = new HashSet<>(); //创建HashSet对象
        boolean b1 = hs.add("a");
        boolean b2 = hs.add("a"); //当向set集合中存储重复元素的时候返回为false
        hs.add("b");
        hs.add("c");
        hs.add("d");
        System.out.println(hs); //HashSet的继承体系中有重写toString方法
        System.out.println(b1);
        System.out.println(b2);

        for (String string : hs) { //只要能用迭代器迭代的,就可以使用增强for循环遍历
          System.out.println(string);
      }
    }

    三、自定义对象保证元素的唯一性  

        /**
          * @param args
          * Set集合,无索引,不可以重复,无序(存取不一致)
      */
          public static void main(String[] args) {
              //demo1();
            HashSet<Person> hs = new HashSet<>();
            hs.add(new Person("张三", 23));
            hs.add(new Person("张三", 23));
            hs.add(new Person("李四", 24));
            hs.add(new Person("李四", 24));
            hs.add(new Person("李四", 24));
            hs.add(new Person("李四", 24));

            //System.out.println(hs.size());
            System.out.println(hs);
        }

    重写hashCode()equals方法      

        /*
          * 为什么是31?
          * 1,31是一个质数,质数是能被1和自己本身整除的数
          * 2,31这个数既不大也不小
          * 3,31这个数好算,2的五次方-1,2向左移动5位
          */
            @Override
            public int hashCode() {
              final int prime = 31;
              int result = 1;
              result = prime * result + age;
              result = prime * result + ((name == null) ? 0 : name.hashCode());
            return result;
          }
          @Override
          public boolean equals(Object obj) {
          if (this == obj) //调用的对象和传入的对象是同一个对象
            return true; //直接返回true
            if (obj == null) //传入的对象为null
            return false; //返回false
            if (getClass() != obj.getClass()) //判断两个对象对应的字节码文件是否是同一个字节码
              return false; //如果不是直接返回false
              Person other = (Person) obj; //向下转型
              if (age != other.age) //调用对象的年龄不等于传入对象的年龄
              return false; //返回false
              if (name == null) { //调用对象的姓名为null
              if (other.name != null) //传入对象的姓名不为null
              return false; //返回false
              } else if (!name.equals(other.name)) //调用对象的姓名不等于传入对象的姓名
              return false; //返回false
              return true; //返回true
            }

    四、LinkedHashSet

      A.概述   

        具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现。此实现与 HashSet 的不同之外在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,即按照将元素插入到 set 中的顺序(插入顺序)进行迭代。注意,插入顺序 受在 set 中重新插入的 元素的影响。(如果在 s.contains(e) 返回 true 后立即调用 s.add(e),则元素 e 会被重新插入到 set s 中。)

    此实现可以让客户免遭未指定的、由 HashSet 提供的通常杂乱无章的排序工作,而又不致引起与 TreeSet 关联的成本增加。使用它可以生成一个与原来顺序相同的 set 副本,并且与原 set 的实现无关:

    五、运用代码 

      /**
        * @param args
        * LinkedHashSet
        * 底层是链表实现的,是set集合中唯一一个能保证怎么存就怎么取的集合对象
        * 因为是HashSet的子类,所以也是保证元素唯一的,与HashSet的原理一样
      */
        public static void main(String[] args) {
          LinkedHashSet<String> lhs = new LinkedHashSet<>();
          lhs.add("a");
          lhs.add("a");
          lhs.add("a");
          lhs.add("a");
          lhs.add("b");
          lhs.add("c");
          lhs.add("d");

          System.out.println(lhs);
      }

     六、TreeSet集合

      A概述

        TreeSet集合是用来对象元素进行排序的,同样他也可以保证元素的唯一
        * 当compareTo方法返回0的时候集合中只有一个元素
        * 当compareTo方法返回正数的时候集合会怎么存就怎么取
        * 当compareTo方法返回负数的时候集合会倒序存储

      B代码演示   

        public static void main(String[] args) {
          //demo1();
          //demo2();
          //demo3();
          //demo4();
          //需求:将字符串按照长度排序
          TreeSet<String> ts = new TreeSet<>(new CompareByLen()); //Comparator c = new CompareByLen();
          ts.add("aaaaaaaa");
          ts.add("z");
          ts.add("wc");
          ts.add("nba");
          ts.add("cba");

          System.out.println(ts);
        }

        public static void demo4() {
          TreeSet<Person> ts = new TreeSet<>();
          ts.add(new Person("zhangsan", 23));
          ts.add(new Person("lisi", 13));
          ts.add(new Person("wangwu", 33));
          ts.add(new Person("zhaoliu", 43));
          ts.add(new Person("aaaa", 53));

          System.out.println(ts);
        }

        public static void demo3() {
          TreeSet<Person> ts = new TreeSet<>();
          ts.add(new Person("李四", 13));
          ts.add(new Person("张三", 23));
          ts.add(new Person("王五", 43));
          ts.add(new Person("赵六", 33));

          System.out.println('张' + 0);
          System.out.println('李' + 0);
          System.out.println('王' + 0);
          System.out.println('赵' + 0);

          System.out.println(ts);
      }

        public static void demo2() {
          TreeSet<Person> ts = new TreeSet<>();
          ts.add(new Person("张三", 23));
          ts.add(new Person("李四", 13));
          ts.add(new Person("周七", 13));
          ts.add(new Person("王五", 43));
          ts.add(new Person("赵六", 33));

          System.out.println(ts);
    }

        public static void demo1() {
          TreeSet<Integer> ts = new TreeSet<>();
          ts.add(3);
          ts.add(1);
          ts.add(1);
          ts.add(2);
          ts.add(2);
          ts.add(3);
          ts.add(3);

          System.out.println(ts);
      }

    }


      class CompareByLen /*extends Object*/ implements Comparator<String> {

        @Override
        public int compare(String s1, String s2) { //按照字符串的长度比较
          int num = s1.length() - s2.length(); //长度为主要条件
          return num == 0 ? s1.compareTo(s2) : num; //内容为次要条件
        }

    }

  • 相关阅读:
    (4)UIView和父子控件
    (2)第一个IOS程序
    svn本地目录结构for window
    (1)xcode基本设置和控制器等介绍
    git版本控制 for window安装和命令行使用
    linux虚拟机如何配置网卡信息(确保两台服务器通信)
    linux系统中firewalld防火墙管理工具firewallcmd(CLI命令行)
    linux系统中firewalld防火墙管理工具firewallconfig(GUI图形用户界面)
    linux系统中使用nmtui命令配置网络参数(图形用户界面)
    网卡是什么?
  • 原文地址:https://www.cnblogs.com/zyyzy/p/12440869.html
Copyright © 2011-2022 走看看