【原】Java学习笔记028 - 集合
生活随笔
收集整理的這篇文章主要介紹了
【原】Java学习笔记028 - 集合
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
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>:一個(gè)不包含重復(fù)元素的 collection。
10 *
11 * 特點(diǎn):
12 * 1、無(wú)序:指的是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 // 通過(guò)查看源碼,發(fā)現(xiàn)會(huì)使用到元素的hashCode,hashCode相同的字符串添加時(shí)不重復(fù)添加
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類(lèi)的源碼
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類(lèi)的源碼
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 // 類(lèi) HashSet<E>:此類(lèi)實(shí)現(xiàn) Set 接口,由哈希表(實(shí)際上是一個(gè) HashMap 實(shí)例)支持。
9 // 它不保證 set 的迭代順序;特別是它不保證該順序恒久不變。此類(lèi)允許使用 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 // 分析:觀察一下創(chuàng)建相同姓名、相同年齡的學(xué)生對(duì)象,它們的hashCode是否一致
19 // 原因在于因?yàn)镾tudent類(lèi)的對(duì)象沒(méi)有重寫(xiě)hashCode方法和equals方法,默認(rèn)使用Object類(lèi)的hashCode方法和equals方法
20
21 System.out.println((new Student("張三", 18)).hashCode()); // 未重寫(xiě)時(shí)的值:118352462 重寫(xiě)后的值:776408
22 System.out.println((new Student("張三", 18)).hashCode()); // 未重寫(xiě)時(shí)的值:1550089733 重寫(xiě)后的值: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 * 類(lèi) LinkedHashSet<E>:具有可預(yù)知迭代順序的 Set 接口的哈希表和鏈接列表實(shí)現(xiàn)。
10 *
11 * 特點(diǎn):有序唯一
12 * 1、唯一:通過(guò)哈希表來(lái)保證唯一
13 * 2、有序:通過(guò)鏈表來(lái)保證元素的有序
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 * 類(lèi) TreeSet<E>:
10 * 基于 TreeMap 的 NavigableSet 實(shí)現(xiàn)。
11 * 使用元素的自然順序?qū)υ剡M(jìn)行排序,或者根據(jù)創(chuàng)建 set 時(shí)提供的 Comparator 進(jìn)行排序,具體取決于使用的構(gòu)造方法。
12 *
13 * 能夠?qū)ζ渲械脑匕凑漳撤N規(guī)則進(jìn)行排序
14 *
15 * 某種規(guī)則:
16 * 1、可以按照自然順序規(guī)則
17 * 2、可以按照自定義排序規(guī)則
18 */
19
20 // 1、自然排序規(guī)則
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:[張三, 張飛, 李四, 王五] 顯然不是根據(jù)拼音的順序
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 // 可以按照自定義排序規(guī)則
9
10 // 思路:
11 // 考慮到Set容器中的元素是無(wú)序且唯一的,要讓他們可以有順序,其實(shí)就是讓它們具備可比較的能力,即實(shí)現(xiàn)Comparable<T>接口
12
13 /*
14 * 接口 Comparable<T>:此接口強(qiáng)行對(duì)實(shí)現(xiàn)它的每個(gè)類(lèi)的對(duì)象進(jìn)行整體排序。這種排序被稱為類(lèi)的自然排序,類(lèi)的 compareTo 方法被稱為它的自然比較方法。
15 *
16 * Comparable<T>接口的常用成員方法:
17 * int compareTo(T o) :比較此對(duì)象與指定對(duì)象的順序。
18 */
19
20 Set<Student> set = new TreeSet<>();
21
22 // 執(zhí)行異常: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 * 強(qiáng)行對(duì)某個(gè)對(duì)象 collection 進(jìn)行整體排序 的比較函數(shù)。
12 * 可以將 Comparator 傳遞給 sort 方法(如 Collections.sort 或 Arrays.sort),從而允許在排序順序上實(shí)現(xiàn)精確控制。
13 * 還可以使用 Comparator 來(lái)控制某些數(shù)據(jù)結(jié)構(gòu)(如有序 set或有序映射)的順序,或者為那些沒(méi)有自然順序的對(duì)象 collection 提供排序。
14 */
15
16 /*
17 * TreeSet類(lèi)的構(gòu)造函數(shù):
18 * TreeSet(Comparator<? super E> comparator) :構(gòu)造一個(gè)新的空 TreeSet,它根據(jù)指定比較器進(jìn)行排序。
19 */
20
21 // 創(chuàng)建比較器對(duì)象
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類(lèi)的構(gòu)造函數(shù)TreeSet(Comparator<? super E> comparator) :構(gòu)造一個(gè)新的空 TreeSet,它根據(jù)指定比較器進(jìn)行排序。
10 // 傳入的是一個(gè)接口,所以考慮使用匿名內(nèi)部類(lèi)
11 // 匿名內(nèi)部類(lèi)寫(xiě)法的優(yōu)點(diǎn):使用了匿名內(nèi)部類(lèi),就不用再制作實(shí)現(xiàn)Comparator接口的實(shí)現(xiàn)類(lèi)了
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 * 字符串的比較時(shí),考慮使用String類(lèi)的compareTo方法
22 * String類(lèi)的常用成員方法:
23 * int compareTo(String anotherString) :按字典順序比較兩個(gè)字符串。
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存儲(chǔ)規(guī)則】
22 // 第一個(gè)元素存儲(chǔ)時(shí),直接作為根節(jié)點(diǎn)存儲(chǔ)
23 // 從第二個(gè)元素開(kāi)始,每個(gè)元素存儲(chǔ)時(shí)從根節(jié)點(diǎn)開(kāi)始比較
24 // 如果比根節(jié)點(diǎn)大,就作為根節(jié)點(diǎn)的右側(cè)
25 // 如果比根節(jié)點(diǎn)小,就作為根節(jié)點(diǎn)的左側(cè)
26 // 如果相等,就無(wú)視
27 // 【TreeSet取出規(guī)則】
28 // 取出時(shí),根據(jù)(前序遍歷、中序遍歷、后序遍歷)
29 // 從根節(jié)點(diǎn)開(kāi)始,按照左、中、右的原則依次取出元素
30
31 // 查看TreeSet類(lèi)的源碼
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類(lèi)的源碼
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類(lèi),放入到TreeSet集合中會(huì)產(chǎn)生執(zhí)行異常: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 // 構(gòu)造函數(shù)
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 // 為了去除重復(fù)內(nèi)容的對(duì)象,需要重寫(xiě)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 "學(xué)生 [姓名為:" + name + ", 年齡為:" + age + "]";
70 }
71
72 // 需要重寫(xiě)compareTo方法進(jìn)行比較
73 // 制定比較的規(guī)則:先比較年齡的大小,年齡相同時(shí)比較姓名的順序
74 @Override
75 public int compareTo(Student anotherStudent) {
76 // 首先按年齡的自然順序
77 int resultAge = this.age - anotherStudent.age;
78
79 /*
80 * 其次按姓名的自然順序
81 * 字符串的比較時(shí),考慮使用String類(lèi)的compareTo方法
82 * String類(lèi)的常用成員方法:
83 * int compareTo(String anotherString) :按字典順序比較兩個(gè)字符串。
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 * 實(shí)現(xiàn)比較器的類(lèi)
7 * 這里沒(méi)有在Student類(lèi)上直接實(shí)現(xiàn)Comparator<T>接口,是因?yàn)镃omparator<T>接口的compare方法比較的是兩個(gè)對(duì)象
8 *
9 * Comparator<T>接口的常用成員方法:
10 * 1、int compare(T o1, T o2) :比較用來(lái)排序的兩個(gè)參數(shù)。
11 * 2、boolean equals(Object obj) :指示某個(gè)其他對(duì)象是否“等于”此 Comparator。
12 *
13 * 注意:因?yàn)镺bject基類(lèi)就有equals方法,所以不顯式進(jìn)行重寫(xiě),就是使用Object基類(lèi)的equals方法,不會(huì)提示語(yǔ)法出錯(cuò)
14 */
15 public class StudentCompartor implements Comparator<Student> {
16 /*
17 * 重寫(xiě)進(jìn)行比較的方法
18 * 制定比較的規(guī)則:先比較年齡的大小,年齡相同時(shí)比較姓名的順序
19 */
20 @Override
21 public int compare(Student student1, Student student2) {
22 // 首先按年齡的自然順序
23 int resultAge = student1.getAge() - student2.getAge();
24
25 /*
26 * 其次按姓名的自然順序
27 * 字符串的比較時(shí),考慮使用String類(lèi)的compareTo方法
28 * String類(lèi)的常用成員方法:
29 * int compareTo(String anotherString) :按字典順序比較兩個(gè)字符串。
30 */
31 int result = (resultAge == 0) ? student1.getName().compareTo(student2.getName()) : resultAge;
32
33 return result;
34 }
35 }
?
轉(zhuǎn)載于:https://www.cnblogs.com/iflytek/p/6591963.html
總結(jié)
以上是生活随笔為你收集整理的【原】Java学习笔记028 - 集合的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Flash中如何使用滤镜
- 下一篇: javascript自定义事件原理