zoukankan      html  css  js  c++  java
  • Collection-Set

    Set:唯一
      --HashSet:无序,唯一
        ----LinkedHashSet:采用的存储为哈希表+链表的结构(java.util.LinkedHashSet实现了Set接口,继承HashSet)
      --TreeSet:唯一,有序(大小顺序)

    Set接口继承Collection接口,没有额外添加方法
      特点:唯一(不重复),无序(位置顺序),无法通过下标索引获取元素
     其下有三个常用的实现类
       HashSet***
        常用的构造函数
          HashSet():构造一个新的空 set,其底层 HashMap 实例的默认初始容量是 16,加载因子是 0.75。
          HashSet(int initialCapacity):构造一个新的空 set,其底层 HashMap 实例具有指定的初始容量和默认的加载因子(0.75)
        常用的函数:
          add(E e):如果此 set 中尚未包含指定元素,则添加指定元素。
          size():获取容器中元素的个数
          iterator():返回对此 set 中元素进行迭代的迭代器。
          isEmpty():如果此 set 不包含任何元素,则返回 true。
          contains(Object o) :如果此 set 包含指定元素,则返回 true。
          remove(Object o):如果指定元素存在于此 set 中,则将其移除。
        遍历方式:
          1.使用for-each遍历
          2.使用迭代器进行遍历
      TreeSet*

      LinkedHashSet

    public class TestHashSet {
        public static void main(String[] args) {
            Set<String> set = new HashSet<String>();
            System.out.println("容器是否为空:"+set.isEmpty());
            set.add("java");
            set.add("oracle");
            set.add("html");
            set.add("java");
            System.out.println("元素的个数:"+set.size());
            System.out.println("容器是否为空:"+set.isEmpty());
            System.out.println("是否包含java:"+set.contains("java"));
            //1.使用for-each进行遍历
            for (String string : set) {
                System.out.println(string);
            }
            System.out.println("------");
            //2.使用迭代器进行遍历
            Iterator<String> iter = set.iterator();
            while(iter.hasNext()){
                String str = iter.next();
                System.out.println(str);
            }
        }
    }

    HashSet存储结构采用hashtable(哈希表+链表结构进行存储)
      优点:
        查询(哈希算法),添加,删除速(链表)度快
        hashcode(哈希码):同哈希码计算对象的存储位置 y=k(x)
        y:代表存储位置 x:哈希码
      缺点:无序(位置顺序),无法通过下标访问--->get(i)
        添加情况:添加时会计算存储位置--->获取哈希码--->通过调用hashcode()获取哈希码
        情况1:一次添加成功
        情况2:多次添加,存在重复,去掉重复项--->通过 equals()内容是否一致
        情况3:在相同位置,多次添加成功
    hashcode()与equals()的关系
      1。hashcode相同,equals()是不一定相同
      2.equals()比较两个对象内容相同(值为true),hashcode值是一定相同

    注意:
      hashSet中去掉重复项会调用hashCode()和equals()
      需要重写Object类中hashCode()和equals()
      1.先调用hashCode()获取对象的hash码,如果hash码不相同,对象肯定不同,不再调用equals方法进行比较
        提高了效率:
          传统做法:如果要比较1000的对象,需要调用1000次的equals()方法
          使用hash码:先比较hash是否相同,如果hash码相同才调用equals进行比较
      2.通过hash码计算存储位置: y=k(x)

    hashCode如何计算:
      1.Integer类型:用自身数值做hashcode
      2.Student

    package cn.zzsxt.set1;
    
    public class Student {
        private String name;
        private int age;
        public Student(){
            
        }
        public Student(String name,int age){
            this.name=name;
            this.age=age;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        
        @Override
        public String toString() {
            return "姓名:"+name+",年龄:"+age;
        }
        @Override
        public int hashCode() {
            System.out.println("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) {
            System.out.println("equals方法被调用了....");
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            Student other = (Student) obj;
            if (age != other.age)
                return false;
            if (name == null) {
                if (other.name != null)
                    return false;
            } else if (!name.equals(other.name))
                return false;
            return true;
        }
    
        
    }
    public class TestHashSet2 {
        public static void main(String[] args) {
            Set<Student> set = new HashSet<Student>();
            Student stu1 = new Student("zhangsan",20);
            Student stu2 = new Student("zhangsan2",22);
            Student stu3 = new Student("zhangsan3",23);
            Student stu4 = new Student("zhangsan2",22);//??
            Student stu5 = new Student("zhangsan2",22);//??
    //        set.add("java"); //一旦使用泛型,该容器只能保存指定的数据类型
            set.add(stu1);
            set.add(stu2);
            set.add(stu3);
            set.add(stu4);
            set.add(stu5);
            System.out.println(set.size());
            for (Student student : set) {
                System.out.println(student);//System.out.println(student.toString());
            }
            
        }
    }

    Set:唯一
        --HashSet:无序,唯一
          ----LinkedHashSet:采用的存储为哈希表+链表的结构
        --TreeSet:唯一,有序(大小顺序)

    java.util.LinkedHashSet实现了Set接口,继承HashSet
      特点:唯一,有序(位置顺序)
      常用的构造函数
        LinkedHashSet():构造一个带默认初始容量 (16) 和加载因子 (0.75) 的新空链接哈希 set。
        LinkedHashSet(int initialCapacity):构造一个带指定初始容量和默认加载因子 (0.75) 的新空链接哈希 set。
      常用方法:
        add(E e):添加
        remove(E e):移除指定元素
        size():查看容器元素的个数
        contains(E e):是否包含指定元素
        iterator():返回一个迭代器

    public class TestLinkedHashSet {
        public static void main(String[] args) {
            LinkedHashSet<String> linkedHashSet = new LinkedHashSet<String>();
            linkedHashSet.add("java");
            linkedHashSet.add("oracle");
            linkedHashSet.add("html");
            linkedHashSet.add("html");
            linkedHashSet.remove("java");//
            System.out.println("元素个数:"+linkedHashSet.size());
            System.out.println("是否包含java:"+linkedHashSet.contains("java"));
            //采用遍历:for-each
            for (String string : linkedHashSet) {
                System.out.println(string);
            }
            System.out.println("--------------------------");
            //采用迭代器:Iterator
            for(Iterator<String> iter = linkedHashSet.iterator();iter.hasNext();){
                String str = iter.next();
                System.out.println(str);
            }
        
        }
    }

    TreeSet:采用二叉树进行存储,实现类Set接口
      特点:唯一,有序(自然顺序)
      优点:
        查找效率比List要高,但没有HashSet高
      构造函数:
        TreeSet():构造一个新的空 set,该 set 根据其元素的自然顺序进行排序。

    public class TestTreeSet {
        public static void main(String[] args) {
            TreeSet<String> treeSet = new TreeSet<String>();
            treeSet.add("java");
            treeSet.add("oracle");
            treeSet.add("html");
            treeSet.add("aa");
            treeSet.add("ab");
    //        treeSet.add("html");
            System.out.println("元素个数:"+treeSet.size());
            //使用for-each遍历
            for (String string : treeSet) {
                System.out.println(string);
            }
        }
    
    }

    TreeSet存储对象的方法

    package cn.zzsxt.set2;
    
    public class Student implements Comparable<Student>{
        
        private String name;
        private int age;
        private int score;
        
        public Student() {
        }
    
        public Student(String name, int age, int score) {
            this.name = name;
            this.age = age;
            this.score = score;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public int getScore() {
            return score;
        }
    
        public void setScore(int score) {
            this.score = score;
        }
    
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + age;
            result = prime * result + ((name == null) ? 0 : name.hashCode());
            result = prime * result + score;
            return result;
        }
    
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            Student other = (Student) obj;
            if (age != other.age)
                return false;
            if (name == null) {
                if (other.name != null)
                    return false;
            } else if (!name.equals(other.name))
                return false;
            if (score != other.score)
                return false;
            return true;
        }
    
        @Override
        public String toString() {
            return "Student [name=" + name + ", age=" + age + ", score=" + score + "]";
        }
        /**
         * 重写Compareable接口中的方法
         * 完成比较业务逻辑
         * 按照分数为第一顺序倒序
         * 年龄为第二顺序进行倒序存放
         * 
         */
        @Override
        public int compareTo(Student o) {
            if(this.score>o.score){
                return -1;
            }else if(this.score==o.score){
                if(this.age>o.age){
                    return -1;
                }else if(this.age==o.age){
                    return 0;
                }else{
                    return 1;
                }
            }else {
                return 1;
            }
        }
        
        
    }

    出现异常:java.lang.ClassCastException
      导致原因:TreeSet采用的二叉树进行存放(对要保存的元素要求有大小顺序,如果要比较对象大小必须实现Compareable接口,重写compareTo方法)
     需求:
      按照分数为第一顺序,年龄为第二顺序进行存放

    public class TestTreeSet {
        public static void main(String[] args) {
            TreeSet<Student> treeSet = new TreeSet<Student>();
            Student stu1 = new Student("zhangsan",20,80);
            Student stu2 = new Student("lisi",21,82);
            Student stu3 = new Student("wangwu",22,80);
            Student stu4 = new Student("wangwu",22,80);
            treeSet.add(stu1);
            treeSet.add(stu2);
            treeSet.add(stu3);
            treeSet.add(stu4);
            for (Student student : treeSet) {
                System.out.println(student);//调用student中的toString()方法
            }
        }
    }

     构造函数:
      TreeSet()构造一个新的空 set,该 set 根据其元素的自然顺序进行排序(本质上调用对象中重写Comparable接口中compareTo方法)。
        构造一个新的空 TreeSet,它根据指定比较器进行排序
      TreeSet(Comparator<? super E> comparator)
        构造一个新的空 TreeSet,它根据指定比较器进行排序。
      java.util.Comparator:比较器接口,可能更加灵活的完成对象的比较

    package cn.zzsxt.set2;
    
    import java.util.Comparator;
    
    public class LengthCom implements Comparator<Student> {
        /**
         * 比较用来排序的两个参数。
         * 根据第一个参数小于、等于或大于第二个参数分别返回负整数、零或正整数
         */
        @Override
        public int compare(Student o1, Student o2) {
            int len1 = o1.getName().length();
            int len2 = o2.getName().length();
            if(len1>len2){
                return 1;
            }else if(len1==len2){
                return 0;
            }else{
                return -1;
            }
        }
    
    }
    public class TestTreeSet2 {
        public static void main(String[] args) {
            //创建一个比较器
            LengthCom lencom = new LengthCom();
            //它根据指定比较器进行排序
            TreeSet<Student> treeSet = new TreeSet<Student>(lencom);
            Student stu1 = new Student("zhangsan",20,80);
            Student stu2 = new Student("lisi",21,82);
            Student stu3 = new Student("wangwu",22,80);
            treeSet.add(stu1);
            treeSet.add(stu2);
            treeSet.add(stu3);
            for (Student student : treeSet) {
                System.out.println(student);//调用student中的toString()方法
            }
        }
    }


    需求:
    按照姓名的长度进行排序

  • 相关阅读:
    在已安装的PHP版本之间切换
    LDAP系列(一)完整的 LDAP + phpLDAPadmin安装部署流程
    如何关闭Windows自动更新
    win10安装SDK、JAVA、Python配置环境变量
    怎么看懂接口文档
    全面解析 Postman 工具
    API接口监控
    jmeter面试题
    Navicat for MySQL 连接数据库
    Linux系统
  • 原文地址:https://www.cnblogs.com/fwdsz/p/6748489.html
Copyright © 2011-2022 走看看