zoukankan      html  css  js  c++  java
  • 【原】Java学习笔记028

     1 package cn.temptation;
     2 
     3 import java.util.HashSet;
     4 import java.util.Set;
     5 
     6 public class Sample01 {
     7     public static void main(String[] args) {
     8         /*
     9          * 接口 Set<E>:一个不包含重复元素的 collection。
    10          * 
    11          * 特点:
    12          * 1、无序:指的是Set显示其元素的顺序 与 放入元素的顺序可能不一致
    13          * 2、唯一:放入其中的元素是唯一的
    14          */
    15         
    16         Set<String> set = new HashSet<>();
    17         
    18         set.add("China");
    19         set.add("USA");
    20         set.add("Japan");
    21         set.add("China");
    22         
    23         System.out.println("set:" + set);        // set:[USA, China, Japan]
    24         
    25         // 通过查看源码,发现会使用到元素的hashCode,hashCode相同的字符串添加时不重复添加
    26         System.out.println("China".hashCode());        // 65078583
    27         System.out.println("USA".hashCode());        // 84323
    28         System.out.println("Japan".hashCode());        // 71341030
    29         System.out.println((new String("China")).hashCode());        // 65078583
    30     }
    31 }
    32 // 查看HashSet类的源码
    33 //public boolean add(E e) {
    34 //    return map.put(e, PRESENT)==null;
    35 //}
    36 
    37 //private transient HashMap<E,Object> map;
    38 
    39 // 查看HashMap类的源码
    40 //public V put(K key, V value) {
    41 //    return putVal(hash(key), key, value, false, true);
    42 //}
     1 package cn.temptation;
     2 
     3 import java.util.HashSet;
     4 import java.util.Set;
     5 
     6 public class Sample02 {
     7     public static void main(String[] args) {
     8         // 类 HashSet<E>:此类实现 Set 接口,由哈希表(实际上是一个 HashMap 实例)支持。
     9         // 它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。此类允许使用 null 元素。
    10         
    11         Set<Student> set = new HashSet<>();
    12         
    13         set.add(new Student("张三", 18));
    14         set.add(new Student("李四", 20));
    15         set.add(new Student("王五", 22));
    16         set.add(new Student("张三", 18));
    17         
    18         // 分析:观察一下创建相同姓名、相同年龄的学生对象,它们的hashCode是否一致
    19         // 原因在于因为Student类的对象没有重写hashCode方法和equals方法,默认使用Object类的hashCode方法和equals方法
    20         
    21         System.out.println((new Student("张三", 18)).hashCode());        // 未重写时的值:118352462            重写后的值:776408
    22         System.out.println((new Student("张三", 18)).hashCode());        // 未重写时的值:1550089733            重写后的值:776408
    23         
    24         System.out.println("set:" + set);
    25     }
    26 }
     1 package cn.temptation;
     2 
     3 import java.util.LinkedHashSet;
     4 import java.util.Set;
     5 
     6 public class Sample03 {
     7     public static void main(String[] args) {
     8         /*
     9          * 类 LinkedHashSet<E>:具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现。
    10          * 
    11          * 特点:有序唯一
    12          * 1、唯一:通过哈希表来保证唯一
    13          * 2、有序:通过链表来保证元素的有序
    14          */
    15         Set<String> set = new LinkedHashSet<>();
    16         
    17         set.add("China");
    18         set.add("USA");
    19         set.add("Japan");
    20         set.add("China");
    21         set.add("France");
    22         set.add("England");
    23         
    24         System.out.println("set:" + set);
    25     }
    26 }
     1 package cn.temptation;
     2 
     3 import java.util.Set;
     4 import java.util.TreeSet;
     5 
     6 public class Sample04 {
     7     public static void main(String[] args) {
     8         /*
     9          * 类 TreeSet<E>:
    10          * 基于 TreeMap 的 NavigableSet 实现。
    11          * 使用元素的自然顺序对元素进行排序,或者根据创建 set 时提供的 Comparator 进行排序,具体取决于使用的构造方法。 
    12          * 
    13          * 能够对其中的元素按照某种规则进行排序
    14          * 
    15          * 某种规则:
    16          * 1、可以按照自然顺序规则
    17          * 2、可以按照自定义排序规则
    18          */
    19         
    20         // 1、自然排序规则
    21         Set<Integer> set1 = new TreeSet<>();
    22         
    23         set1.add(1);
    24         set1.add(3);
    25         set1.add(2);
    26         set1.add(4);
    27         
    28         System.out.println("treeset:" + set1);        // treeset:[1, 2, 3, 4]
    29         
    30         System.out.println("-------------------------------------------");
    31         
    32         Set<Character> set2 = new TreeSet<>();
    33         
    34         set2.add('j');
    35         set2.add('A');
    36         set2.add('v');
    37         set2.add('a');
    38         set2.add('G');
    39         set2.add('O');
    40         set2.add('o');
    41         set2.add('D');
    42         
    43         System.out.println("treeset:" + set2);        // treeset:[A, D, G, O, a, j, o, v]
    44         
    45         System.out.println("-------------------------------------------");
    46         
    47         Set<String> set3 = new TreeSet<>();
    48         
    49         set3.add("USA");
    50         set3.add("China");
    51         set3.add("Japan");
    52         set3.add("Chile");
    53         
    54         System.out.println("treeset:" + set3);        // treeset:[Chile, China, Japan, USA]
    55         
    56         System.out.println("-------------------------------------------");
    57         
    58         Set<String> set4 = new TreeSet<>();
    59         
    60         set4.add("张三");
    61         set4.add("李四");
    62         set4.add("王五");
    63         set4.add("张飞");
    64         
    65         System.out.println("treeset:" + set4);        // treeset:[张三, 张飞, 李四, 王五]        显然不是根据拼音的顺序
    66         
    67         System.out.println((int)'张' + " VS " + (int)'李' + " VS " + (int)'王');        // 24352 VS 26446 VS 29579
    68         System.out.println((int)'三' + " VS " + (int)'飞');                                // 19977 VS 39134
    69     }
    70 }
     1 package cn.temptation;
     2 
     3 import java.util.Set;
     4 import java.util.TreeSet;
     5 
     6 public class Sample05 {
     7     public static void main(String[] args) {
     8         // 可以按照自定义排序规则
     9         
    10         // 思路:
    11         // 考虑到Set容器中的元素是无序且唯一的,要让他们可以有顺序,其实就是让它们具备可比较的能力,即实现Comparable<T>接口
    12         
    13         /*
    14          * 接口 Comparable<T>:此接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的 compareTo 方法被称为它的自然比较方法。
    15          * 
    16          * Comparable<T>接口的常用成员方法:
    17          * int compareTo(T o) :比较此对象与指定对象的顺序。 
    18          */
    19         
    20         Set<Student> set = new TreeSet<>();
    21         
    22         // 执行异常:java.lang.ClassCastException: cn.temptation.Student cannot be cast to java.lang.Comparable
    23         set.add(new Student("张三", 20));
    24         set.add(new Student("李四", 18));
    25         set.add(new Student("王五", 22));
    26         set.add(new Student("张飞", 20));
    27         
    28         for (Student item : set) {
    29             System.out.println(item);
    30         }
    31     }
    32 }
     1 package cn.temptation;
     2 
     3 import java.util.Comparator;
     4 import java.util.Set;
     5 import java.util.TreeSet;
     6 
     7 public class Sample06 {
     8     public static void main(String[] args) {
     9         /*
    10          * 接口 Comparator<T>:
    11          * 强行对某个对象 collection 进行整体排序 的比较函数。
    12          * 可以将 Comparator 传递给 sort 方法(如 Collections.sort 或 Arrays.sort),从而允许在排序顺序上实现精确控制。
    13          * 还可以使用 Comparator 来控制某些数据结构(如有序 set或有序映射)的顺序,或者为那些没有自然顺序的对象 collection 提供排序。
    14          */
    15         
    16         /*
    17          * TreeSet类的构造函数:
    18          * TreeSet(Comparator<? super E> comparator) :构造一个新的空 TreeSet,它根据指定比较器进行排序。
    19          */
    20         
    21         // 创建比较器对象
    22         Comparator<Student> comparator = new StudentCompartor();
    23         
    24         Set<Student> set = new TreeSet<>(comparator);
    25         
    26         set.add(new Student("张三", 20));
    27         set.add(new Student("李四", 18));
    28         set.add(new Student("王五", 22));
    29         set.add(new Student("张飞", 20));
    30         
    31         for (Student item : set) {
    32             System.out.println(item);
    33         }
    34     }
    35 }
     1 package cn.temptation;
     2 
     3 import java.util.Comparator;
     4 import java.util.Set;
     5 import java.util.TreeSet;
     6 
     7 public class Sample07 {
     8     public static void main(String[] args) {
     9         // 观察到TreeSet类的构造函数TreeSet(Comparator<? super E> comparator) :构造一个新的空 TreeSet,它根据指定比较器进行排序。
    10         // 传入的是一个接口,所以考虑使用匿名内部类
    11         // 匿名内部类写法的优点:使用了匿名内部类,就不用再制作实现Comparator接口的实现类了
    12         
    13         Set<Student> set = new TreeSet<>(new Comparator<Student>() {
    14             @Override
    15             public int compare(Student student1, Student student2) {
    16                 // 首先按年龄的自然顺序
    17                 int resultAge = student1.getAge() - student2.getAge();
    18                 
    19                 /* 
    20                  * 其次按姓名的自然顺序
    21                  * 字符串的比较时,考虑使用String类的compareTo方法
    22                  * String类的常用成员方法:
    23                  * int compareTo(String anotherString) :按字典顺序比较两个字符串。 
    24                  */
    25                 int result = (resultAge == 0) ? student1.getName().compareTo(student2.getName()) : resultAge;
    26                 
    27                 return result;
    28             }
    29         });
    30         
    31         set.add(new Student("张三", 20));
    32         set.add(new Student("李四", 18));
    33         set.add(new Student("王五", 22));
    34         set.add(new Student("张飞", 20));
    35         
    36         for (Student item : set) {
    37             System.out.println(item);
    38         }
    39     }
    40 }
     1 package cn.temptation;
     2 
     3 import java.util.Set;
     4 import java.util.TreeSet;
     5 
     6 public class Sample08 {
     7     public static void main(String[] args) {
     8         Set<Integer> set = new TreeSet<>();
     9         
    10         set.add(1);
    11         set.add(5);
    12         set.add(4);
    13         set.add(2);
    14         set.add(3);
    15         
    16         for (Integer item : set) {
    17             System.out.println(item);
    18         }
    19     }
    20 }
    21 // 【TreeSet存储规则】
    22 // 第一个元素存储时,直接作为根节点存储
    23 // 从第二个元素开始,每个元素存储时从根节点开始比较
    24 //        如果比根节点大,就作为根节点的右侧
    25 //      如果比根节点小,就作为根节点的左侧
    26 //        如果相等,就无视
    27 // 【TreeSet取出规则】
    28 // 取出时,根据(前序遍历、中序遍历、后序遍历)
    29 // 从根节点开始,按照左、中、右的原则依次取出元素
    30 
    31 // 查看TreeSet类的源码
    32 //public boolean add(E e) {
    33 //    return m.put(e, PRESENT)==null;
    34 //}
    35 
    36 //private transient NavigableMap<E,Object> m;
    37 
    38 //查看TreeMap类的源码
    39 //public V put(K key, V value) {
    40 //    Entry<K,V> t = root;
    41 //    if (t == null) {
    42 //        compare(key, key); // type (and possibly null) check
    43 //
    44 //        root = new Entry<>(key, value, null);
    45 //        size = 1;
    46 //        modCount++;
    47 //        return null;
    48 //    }
    49 //    int cmp;
    50 //    Entry<K,V> parent;
    51 //    // split comparator and comparable paths
    52 //    Comparator<? super K> cpr = comparator;
    53 //    if (cpr != null) {
    54 //        do {
    55 //            parent = t;
    56 //            cmp = cpr.compare(key, t.key);
    57 //            if (cmp < 0)
    58 //                t = t.left;
    59 //            else if (cmp > 0)
    60 //                t = t.right;
    61 //            else
    62 //                return t.setValue(value);
    63 //        } while (t != null);
    64 //    }
    65 //    else {
    66 //        if (key == null)
    67 //            throw new NullPointerException();
    68 //        @SuppressWarnings("unchecked")
    69 //            Comparable<? super K> k = (Comparable<? super K>) key;
    70 //        do {
    71 //            parent = t;
    72 //            cmp = k.compareTo(t.key);
    73 //            if (cmp < 0)
    74 //                t = t.left;
    75 //            else if (cmp > 0)
    76 //                t = t.right;
    77 //            else
    78 //                return t.setValue(value);
    79 //        } while (t != null);
    80 //    }
    81 //    Entry<K,V> e = new Entry<>(key, value, parent);
    82 //    if (cmp < 0)
    83 //        parent.left = e;
    84 //    else
    85 //        parent.right = e;
    86 //    fixAfterInsertion(e);
    87 //    size++;
    88 //    modCount++;
    89 //    return null;
    90 //}
     1 package cn.temptation;
     2 
     3 // 注意:只定义Student类,放入到TreeSet集合中会产生执行异常:java.lang.ClassCastException: cn.temptation.Student cannot be cast to java.lang.Comparable
     4 //public class Student {
     5 public class Student implements Comparable<Student> {
     6     // 成员变量
     7     private String name;
     8     private int age;
     9 
    10     // 构造函数
    11     public Student() {
    12         super();
    13     }
    14 
    15     public Student(String name, int age) {
    16         super();
    17         this.name = name;
    18         this.age = age;
    19     }
    20 
    21     // 成员方法
    22     public String getName() {
    23         return name;
    24     }
    25 
    26     public void setName(String name) {
    27         this.name = name;
    28     }
    29 
    30     public int getAge() {
    31         return age;
    32     }
    33 
    34     public void setAge(int age) {
    35         this.age = age;
    36     }
    37 
    38     // 为了去除重复内容的对象,需要重写hashCode方法和equals方法
    39     @Override
    40     public int hashCode() {
    41         final int prime = 31;
    42         int result = 1;
    43         result = prime * result + age;
    44         result = prime * result + ((name == null) ? 0 : name.hashCode());
    45         return result;
    46     }
    47 
    48     @Override
    49     public boolean equals(Object obj) {
    50         if (this == obj)
    51             return true;
    52         if (obj == null)
    53             return false;
    54         if (getClass() != obj.getClass())
    55             return false;
    56         Student other = (Student) obj;
    57         if (age != other.age)
    58             return false;
    59         if (name == null) {
    60             if (other.name != null)
    61                 return false;
    62         } else if (!name.equals(other.name))
    63             return false;
    64         return true;
    65     }
    66     
    67     @Override
    68     public String toString() {
    69         return "学生 [姓名为:" + name + ", 年龄为:" + age + "]";
    70     }
    71 
    72     // 需要重写compareTo方法进行比较
    73     // 制定比较的规则:先比较年龄的大小,年龄相同时比较姓名的顺序
    74     @Override
    75     public int compareTo(Student anotherStudent) {
    76         // 首先按年龄的自然顺序
    77         int resultAge = this.age - anotherStudent.age;
    78         
    79         /* 
    80          * 其次按姓名的自然顺序
    81          * 字符串的比较时,考虑使用String类的compareTo方法
    82          * String类的常用成员方法:
    83          * int compareTo(String anotherString) :按字典顺序比较两个字符串。 
    84          */
    85         int result = (resultAge == 0) ? this.name.compareTo(anotherStudent.name) : resultAge;
    86         
    87         return result;
    88     }
    89 }
     1 package cn.temptation;
     2 
     3 import java.util.Comparator;
     4 
     5 /**
     6  * 实现比较器的类
     7  * 这里没有在Student类上直接实现Comparator<T>接口,是因为Comparator<T>接口的compare方法比较的是两个对象
     8  * 
     9  * Comparator<T>接口的常用成员方法:
    10  * 1、int compare(T o1, T o2) :比较用来排序的两个参数。 
    11  * 2、boolean equals(Object obj) :指示某个其他对象是否“等于”此 Comparator。
    12  * 
    13  * 注意:因为Object基类就有equals方法,所以不显式进行重写,就是使用Object基类的equals方法,不会提示语法出错
    14  */
    15 public class StudentCompartor implements Comparator<Student> {
    16     /*
    17      * 重写进行比较的方法
    18      * 制定比较的规则:先比较年龄的大小,年龄相同时比较姓名的顺序
    19      */
    20     @Override
    21     public int compare(Student student1, Student student2) {
    22         // 首先按年龄的自然顺序
    23         int resultAge = student1.getAge() - student2.getAge();
    24         
    25         /* 
    26          * 其次按姓名的自然顺序
    27          * 字符串的比较时,考虑使用String类的compareTo方法
    28          * String类的常用成员方法:
    29          * int compareTo(String anotherString) :按字典顺序比较两个字符串。 
    30          */
    31         int result = (resultAge == 0) ? student1.getName().compareTo(student2.getName()) : resultAge;
    32         
    33         return result;
    34     }
    35 }
  • 相关阅读:
    增加文章
    网站之注册
    C#常用的引用
    Session.Abandon和Session.Clear有何不同 (转)
    C#文件路径的写法
    UpdatePanel的用法详解
    [转]asp:ScriptManager
    Git 常用命令
    AJAX请求 $.post方法的使用
    a 标签中调用js的几种方法
  • 原文地址:https://www.cnblogs.com/iflytek/p/6591963.html
Copyright © 2011-2022 走看看