• 复习java基础第三天(集合:Collection、Set、HashSet、LinkedHashSet、TreeSet)


    一、Collection常用的方法

    Java 集合可分为 Set、List 和 Map 三种体系:

    Set:无序、不可重复的集合。

    List:有序,可重复的集合。

    Map:具有映射关系的集合。

    Collection 接口是 List、Set 和 Queue 接口的父接口,

    该接口里定义的方法既可用于操作 Set 集合,也可用于操作 List 和 Queue 集合:

    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.HashSet;
    import java.util.Iterator;
    
    public class TestCollections {
    
        public static void main(String[] args) {
            
            //1. 创建一个 Collection 接口的对象. 
            Collection collection = new ArrayList();
        
            //2. Collection 重要方法说明:         
            /**
             * 2.1 用于添加元素的:
             * add()
             * addAll()
             */
            Person p1 = new Person();
            collection.add(p1);
            collection.add(new Person());
            
            Collection collection2 = new ArrayList();
            collection2.add(new Person());
            collection2.add(new Person());
    
            collection.addAll(collection2);
            
            System.out.println(collection.size()); 
            
            /**
             * 2.2 用于访问集合的方法: 
             * 获取集合的长度: size()
             * 对集合进行遍历的方法: iterator() 可以得到对应的 Iterator 接口对象. 
             * 
             * Iterator: 迭代器
             * ①. 获取 Iterator 接口对象: 
             * ②. 使用 while 循环和 Iterator 对象遍历集合中的每一个元素. 具体使用 Iterator 接口的
             *    hasNext() 和 next() 方法. 
             */
            Iterator iterator = collection.iterator();
            
            while(iterator.hasNext()){
                Object obj = iterator.next();
                System.out.println(obj); 
            }
            
            /**
             * 2.3 移除集合中的元素: 
             * remove(): 移除某一个指定的对象. 通过 equals() 方法来判断要移除的那个元素在集合中是否存在.
                         以及是否能够成功移除. 
             * removeAll()
             * clear(): 使集合中的元素置空. 
             */
    //        collection.clear();
            
    //        boolean result = collection.remove(p1);
    //        System.out.println(result); 
    //        
    //        result = collection.removeAll(collection2);
    //        
    //        System.out.println(collection.size()); 
            
            /**
             * 2.4 用于检测集合的方法
             * retains()
             * retainsAll()
             * isEmpty()
             */
            System.out.println(collection.contains(new Person()));//false
            System.out.println(collection.contains(p1));//true
            System.out.println(collection.containsAll(collection2));//true
            
            System.out.println(collection.isEmpty()); //false
    //      collection.clear();
            System.out.println(collection.isEmpty()); //true
            
            /**
             * 2.5 其他方法
             * toArray(): 
             * **T [] toArray(T[]): 涉及到泛型, 后面再说. 
             * 
             * equals(): 比较两个集合是否相等. 
             * hasCode(): 
             */
            Object [] objs = collection.toArray();
            System.out.println(objs.length); //4
            
            Person p2 = new Person();
            
            Collection collection3 = new HashSet();//可换ArrayList()试试
            collection3.add(p1);
            collection3.add(p2);
            
            Collection collection4 = new HashSet();
            collection4.add(p2);
            collection4.add(p1);
            
            System.out.println(collection3.equals(collection4)); 
            
            /**
             * 使用增强 for 循环的方式来对集合进行遍历
             */
            for(Object obj: collection){
                System.out.println(obj); 
            }
        }
    }
    class Person(){}
    练习代码

    二、Set、HashSet、LinkedHashSet

    Set 集合不允许包含相同的元素,如果试把两个相同的元素加入同一个 Set 集合中,则添加操作失败

    Set 判断两个对象是否相同不是使用 == 运算符,而是根据 equals 方法

    注意:

    1、当向 HashSet 集合中存入一个元素时,HashSet 会调用该对象的 hashCode() 方法来得到该对象的

         hashCode 值, 然后根据 hashCode 值决定该对象在 HashSet 中的存储位置

    2、如果两个元素的 equals() 方法返回 true,但它们的 hashCode() 返回值不相等,hashSet 将会

        把它们存储在不同的位置,但依然可以添加成功。

    3、HashSet 集合判断两个元素相等的标准:两个对象通过 equals() 方法比较相等,并且两个对象的 

        hashCode() 方法返回值也相等。即:如果两个对象通过 equals() 方法返回 true,这两个对象的

        hashCode 值也应该相同

    重写 hashCode() 方法的基本原则:

    1、在程序运行时,同一个对象多次调用 hashCode() 方法应该返回相同的值。

    2、当两个对象的 equals() 方法比较返回 true 时,这两个对象的 hashCode() 方法的返回值也应相等。

    3、对象中用作 equals() 方法比较的 Field,都应该用来计算 hashCode 值。

    另外:

    1、LinkedHashSet 是 HashSet 的子类。

    2、LinkedHashSet 集合根据元素的 hashCode 值来决定元素的存储位置,但它同时使用链表维护元素的次序,

         这使得元素看起来是以插入顺序保存的。

    3、LinkedHashSet 性能插入性能略低于 HashSet,但在迭代访问 Set 里的全部元素时有很好的性能。

    4、LinkedHashSet 有序但不允许集合元素重复

    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.LinkedHashSet;
    import java.util.Set;
    
    /**
     * 1. Set 是 Collection 的子接口
     * 2. Set 中不允许存放相同的元素. 判定相同元素的标准是, 两个对象各调用 equals() 方法, 返回 true
     * 3. HashSet
     * 3.1 基本特征:
     * ①. 不能保证元素的排列顺序
     * ②. HashSet 不是线程安全的
     * ③. 集合元素可以使 null
     * ④. 对于 HashSet: 如果两个对象通过 equals() 方法返回 true,这两个对象的 hashCode 值也应该相同。
     * 
     * 4. LinkedHashSet:
     * 4.1 LinkedHashSet 是 HashSet 的子类
     * 4.2 使用链表维护元素的次序,这使得元素看起来是以插入顺序保存的
     * 4.3 LinkedHashSet 不允许集合元素重复
     */
    public class TestSet {
    
        public static void main(String[] args) {
            
            Set set = new LinkedHashSet();
                    //new HashSet();
            
            set.add(null);
            System.out.println(set.size()); //1
            
            Person p1 = new Person();
            set.add(p1);
            set.add(p1);
    
            System.out.println(set.size()); //2
            
            set.add(new Person("AA", 12));
            set.add(new Person("AA", 12));
    
            System.out.println(set.size()); //3
            
            set.add(new Person("FF", 13));
            
            Iterator it = set.iterator();
            while(it.hasNext()){
                System.out.println(it.next()); 
            }
        }
    }
    
     class Person {
    
    //    @Override
    //    public boolean equals(Object obj) {
    //        return false;
    //    }
        
        private String name;
        private int 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;
        }
    
        public Person() {
            // TODO Auto-generated constructor stub
        }
        
        public Person(String name, int age) {
            super();
            this.name = name;
            this.age = age;
        }
        
    //    private static int init = 0;
        
        @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;
            
    //    return init++;
        }
        
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            Person other = (Person) 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;
        }
        
        @Override
        public String toString() {
            return "Person [name=" + name + ", age=" + age + "]";
        }    
    }
    练习代码

    三、TreeSet:

    TreeSet 是 SortedSet 接口的实现类,TreeSet 可以确保集合元素处于排序状态

    TreeSet 支持两种排序方法:自然排序和定制排序默认情况下,TreeSet 采用自然排序

    排序:

    1、TreeSet 会调用集合元素的 compareTo(Object obj) 方法来比较元素之间的大小关系,

         然后将集合元素按升序排列。

    2、如果试图把一个对象添加到 TreeSet 时,则该对象的类必须实现 Comparable 接口

    3、实现 Comparable 的类必须实现 compareTo(Object obj) 方法,两个对象即通过

        compareTo(Object obj)方法的返回值来比较大小

    Comparable 的典型实现:

    BigDecimal、BigInteger 以及所有的数值型对应的包装类:按它们对应的数值大小进行比较。

         Character:   按字符的 UNICODE 值来进行比较。

         Boolean:     true 对应的包装类实例大于 false 对应的包装类实例。

          String:       按字符串中字符的 UNICODE 值进行比较。

      Date、Time:   后边的时间、日期比前面的时间、日期大。

    注意:

    因为只有相同类的两个实例才会比较大小,所以向 TreeSet 中添加的应该是同一个类的对象

    需要把一个对象放入 TreeSet 中,重写该对象对应的 equals() 方法时,应保证该方法与

    compareTo(Object obj) 方法有一致的结果:即如果两个对象通过 equals() 方法比较返回 true,

    则通过 compareTo(Object obj) 方法比较应返回 0.

    import java.util.*;
    
    /*
    Set:无序,不可以重复元素。
        |--HashSet:数据结构是哈希表。线程是非同步的。
                    保证元素唯一性的原理:判断元素的hashCode值是否相同。
                    如果相同,还会继续判断元素的equals方法,是否为true。
    
        |--TreeSet:可以对Set集合中的元素进行排序。
                    底层数据结构是二叉树。
                    保证元素唯一性的依据:
                    compareTo方法return 0.
    
                    TreeSet排序的第一种方式:让元素自身具备比较性。
                    元素需要实现Comparable接口,覆盖compareTo方法。
                    也种方式也成为元素的自然顺序,或者叫做默认顺序。
    
                    TreeSet的第二种排序方式。
                    当元素自身不具备比较性时,或者具备的比较性不是所需要的。
                    这时就需要让集合自身具备比较性。
                    在集合初始化时,就有了比较方式。
    
    需求:
    往TreeSet集合中存储自定义对象学生。
    想按照学生的年龄进行排序。
    
    记住,排序时,当主要条件相同时,一定判断一下次要条件。
    */
    
    class TreeSetDemo 
    {
        public static void main(String[] args) 
        {
            TreeSet ts = new TreeSet();
    
            ts.add(new Student("lisi02",22));
            ts.add(new Student("lisi007",20));
            ts.add(new Student("lisi09",19));
            ts.add(new Student("lisi08",19));
            //ts.add(new Student("lisi007",20));
            //ts.add(new Student("lisi01",40));
    
            Iterator it = ts.iterator();
            while(it.hasNext())
            {
                Student stu = (Student)it.next();
                System.out.println(stu.getName()+"..."+stu.getAge());
            }
        }
    }
    
    class Student implements Comparable//该接口强制让学生具备比较性。
    {
        private String name;
        private int age;
    
        Student(String name,int age)
        {
            this.name = name;
            this.age = age;
        }
    
        public int compareTo(Object obj)
        {
    
            //return 0;        
            if(!(obj instanceof Student))
                throw new RuntimeException("不是学生对象");
            Student s = (Student)obj;
    
            System.out.println(this.name+"....compareto....."+s.name);
            if(this.age>s.age)
                return 1;
            if(this.age==s.age)
            {
                return this.name.compareTo(s.name);
            }
            return -1;
        }
    
        public String getName()
        {
            return name;
        }
        public int getAge()
        {
            return age;
        }
    }
    练习代码(自然排序)
    import java.util.*;
    
    /*
    当元素自身不具备比较性,或者具备的比较性不是所需要的。
    这时需要让容器自身具备比较性。
    定义了比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。
    
    当两种排序都存在时,以比较器为主。
    
    定义一个类,实现Comparator接口,覆盖compare方法。
    */
    class Student implements Comparable//该接口强制让学生具备比较性。
    {
        private String name;
        private int age;
    
        Student(String name,int age)
        {
            this.name = name;
            this.age = age;
        }
    
        public int compareTo(Object obj)
        {
    
            //return 0;
            
            if(!(obj instanceof Student))
                throw new RuntimeException("不是学生对象");
            Student s = (Student)obj;
    
            //System.out.println(this.name+"....compareto....."+s.name);
            if(this.age>s.age)
                return 1;
            if(this.age==s.age)
            {
                return this.name.compareTo(s.name);
            }
            return -1;
        }
    
        public String getName()
        {
            return name;
    
        }
        public int getAge()
        {
            return age;
        }
    }
    class TreeSetDemo2 
    {
        public static void main(String[] args) 
        {
            TreeSet ts = new TreeSet();
    
            ts.add(new Student("lisi02",22));
            ts.add(new Student("lisi02",21));
            ts.add(new Student("lisi007",20));
            ts.add(new Student("lisi09",19));
            ts.add(new Student("lisi06",18));
            ts.add(new Student("lisi06",18));
            ts.add(new Student("lisi007",29));
            //ts.add(new Student("lisi007",20));
            //ts.add(new Student("lisi01",40));
    
            Iterator it = ts.iterator();
            while(it.hasNext())
            {
                Student stu = (Student)it.next();
                System.out.println(stu.getName()+"..."+stu.getAge());
            }
        }
    }
    
    class MyCompare implements Comparator
    {
        public int compare(Object o1,Object o2)
        {
            Student s1 = (Student)o1;
            Student s2 = (Student)o2;
    
            int num = s1.getName().compareTo(s2.getName());
            if(num==0)
            {
    
                return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
                /*
                if(s1.getAge()>s2.getAge())
                    return 1;
                if(s1.getAge()==s2.getAge())
                    return 0;
                return -1;
                */
            }
                    
            return num;
        }
    }
    练习代码(定制排序)

    比较推荐的定制排序做法

    1、首先,定义一个Person类

    public class Person {
         private String name;
         private int 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;
        }
        public Person(String name, int age) {
            super();
            this.name = name;
            this.age = age;
        }
        public Person(){}
    }
    Person类

    (附加的练习:Student类)

    public class Student implements Comparable{
        
        private String name;
        private int 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;
        }
        public Student(String name, int age) {
            super();
            this.name = name;
            this.age = age;
        }
        
        @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;
            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;
        }
        
        @Override
        public int compareTo(Object o) {
            int result;
            if(o instanceof Student){
                Student stu = (Student)o;
                result = this.age-stu.age;
                if(result==0){
                return this.getName().compareTo(stu.getName());
                }
            }else{
                throw new ClassCastException("不是一个学生对象!");
            }
            return result;
        }
        
        public Student(){}
        @Override
        public String toString() {
            return "Student [name=" + name + ", age=" + age + "]";
        }        
    }
    Student类

    2、然后写主程序类

    import java.util.Comparator;
    import java.util.Iterator;
    import java.util.Set;
    import java.util.TreeSet;
    
    public class TestTreeSet {
          public static void main(String []args){
    /*          Set set = new TreeSet();
    //          set.add("123");
    //          set.add(123);
    //          set.add(null);
    //          set.add(new Student());
              set.add(new Student("lisi07",22));
              set.add(new Student("lisi02",16));
              set.add(new Student("lisi008",22));
              set.add(new Student("lisi10",19));
              
              Iterator iterator = set.iterator();
              while(iterator.hasNext()){
                  Student stu = (Student) iterator.next();
                  System.out.println(stu.getName()+"...."+stu.getAge());
              }
              
              for(Object obj:set){
                  System.out.println(obj);
              }*/
              
              Comparator comparator = new  Comparator() {
    
                @Override
                public int compare(Object o1, Object o2) {
                    int result;
                      if(o1 instanceof Person&& o2 instanceof Person){
                          Person p1 = (Person) o1;
                          Person p2 = (Person) o2;
                          result = p1.getAge() - p2.getAge();
                        if(result == 0){
                            return p1.getName().compareTo(p2.getName());
                          }
                      }else{
                          throw new ClassCastException("不能转换为Person");
                     }   
                      return result;
                }
            };
            
            Set set2 = new TreeSet(comparator);
            set2.add(new Person("lisi006",12));
            set2.add(new Person("lisi002",6));
            set2.add(new Person("lisi015",20));
            set2.add(new Person("lisi013",20));
            
            Iterator iterator = set2.iterator();
            while(iterator.hasNext()){
                Person p = (Person) iterator.next();
                System.out.println(p.getName()+" "+p.getAge()+"	");         
            }    
        }
    }
    主程序
  • 相关阅读:
    Java jni字符串转换
    Python读取PE文件(exe/dll)中的时间戳
    深度学习word embedding猜测性别初探
    闪存内容汇编(截止20170405)
    如何自动化安装字体(命令行批量)
    如何分析进程的内存占用问题
    Python print报ascii编码异常的靠谱解决办法
    Linux界面自动化测试框架不完全汇总
    Qt实现同步(阻塞式)http get等网络访问操作
    基于第三方开源库的OPC服务器开发指南(4)——后记:与另一个开源库opc workshop库相关的问题
  • 原文地址:https://www.cnblogs.com/shellway/p/3709074.html
Copyright © 2020-2023  润新知