image.png
    image.png

    image.png
    image.pngimage.png
    image.png
    image.png
    image.png
    image.png

    /*
    1.Set接口的框架
    |——Collection接口:单列集合,用来存储一个一个的对象

    |——Set接口:存储无序的、不可重复的数据 —->高中讲的“集合”
    |——HashSet:作为Set接口的主要实现类;线程不安全的;可以存储null值。
    |——LinkedHashSet:作为HashSet的子类;遍历其内部数据时,可以按照添加的顺序遍历
    优点:对于频繁的遍历操作,LinkedHashSet效率要高于HashSet
    |——TreeSet:可以按照添加的对象的指定属性,进行排序。


    2.Set接口中没有额外定义新的方法,使用的都是Collection中声明过的方法。

    3.要求;向Set中添加的数据,其所在的类一定要重写hashCode()和equals()
    要求:重写的hashCode()和equals()尽可能保持一致性:相等的对象必须具有相等的散列码
    重写两个方法的小技巧:对象中用作equals()方法比较的Field,都应该用来计算hashCode值。
    *

    **
    /
    一、Set:存储无序的、不可重复的数据
    以HashSet为例说明:
    1.无序性:不等于随机性。存储的数据在数组中并非按照数组索引的顺序添加,而是根据数据的哈希值决定的。
    2.不可重复性:保证添加的元素按照equals()判断时,不能返回true,即:相同的元素只能添加一个。
    二、添加元素的过程:以HashSet为例:
    我们向HashSet中添加元素a,首先调用元素a所在类的hashCode()方法,计算元素a的哈希值,
    此哈希值接着通过某种算法计算出在HashSet底层数组中存放的位置(即为:索引位置),
    判断此位置上是否已经有元素:
    如果此位置上没有其他元素,则元素a添加成功。——>情况1
    如归此位置上有其他元素b(或以链表形式存在的多个元素),则比较元素a与元素b的hash值:
    如果hash值不相同,则元素a添加成功。—->情况2
    如果hash值相同,进而需要调用元素a所在类的equals()方法:
    equals()返回true,元素a添加失败
    equals()返回false,则元素a添加成功。—->情况3
    对于添加成功的情况2和情况3而言:元素a与已经存在指定索引位置上数据以链表的方式存储。
    JDK 7:元素a放到数组中,指向原来的数据
    JDK 8:原来的元素在数组中,指向元素a
    总结:七上八下
    HashSet底层:数组+链表的结构
    /

    *
    /
    1.向TreeSet中添加的数据,要求是相同类的对象。
    2.两种排序方式:自然排序(实现Comparable接口) 和 定制排序(Comparator)
    3.自然排序中,比较两个对象是否相同的标准为:comparableTo()返回0,不再是equals()。
    4.定制排序中,比较两个对象是否相同的标准为:compare()返回0,不再是equals()。
    /

    1. package com.atguigu.java2;
    2. import com.atguigu.java1.Person;
    3. import org.junit.Test;
    4. import java.util.*;
    5. /**
    6. * 1.Set接口的框架
    7. * |----Collection接口:单列集合,用来存储一个一个的对象
    8. *
    9. * |----Set接口:存储无序的、不可重复的数据 --->高中讲的“集合”
    10. * |----HashSet:作为Set接口的主要实现类;线程不安全的;可以存储null值。
    11. * |----LinkedHashSet:作为HashSet的子类;遍历其内部数据时,可以按照添加的顺序遍历
    12. * 优点:对于频繁的遍历操作,LinkedHashSet效率要高于HashSet
    13. * |----TreeSet:可以按照添加的对象的指定属性,进行排序。
    14. *
    15. *
    16. * 2.Set接口中没有额外定义新的方法,使用的都是Collection中声明过的方法。
    17. *
    18. * 3.要求;向Set中添加的数据,其所在的类一定要重写hashCode()和equals()
    19. * 要求:重写的hashCode()和equals()尽可能保持一致性:相等的对象必须具有相等的散列码
    20. * 重写两个方法的小技巧:对象中用作equals()方法比较的Field,都应该用来计算hashCode值。
    21. *
    22. * @author Dxkstart
    23. * @create 2021-05-20 19:36
    24. */
    25. public class SetTest {
    26. /*
    27. 一、Set:存储无序的、不可重复的数据
    28. 以HashSet为例说明:
    29. 1.无序性:不等于随机性。存储的数据在数组中并非按照数组索引的顺序添加,而是根据数据的哈希值决定的。
    30. 2.不可重复性:保证添加的元素按照equals()判断时,不能返回true,即:相同的元素只能添加一个。
    31. 二、添加元素的过程:以HashSet为例:
    32. 我们向HashSet中添加元素a,首先调用元素a所在类的hashCode()方法,计算元素a的哈希值,
    33. 此哈希值接着通过某种算法计算出在HashSet底层数组中存放的位置(即为:索引位置),
    34. 判断此位置上是否已经有元素:
    35. 如果此位置上没有其他元素,则元素a添加成功。---->情况1
    36. 如归此位置上有其他元素b(或以链表形式存在的多个元素),则比较元素a与元素b的hash值:
    37. 如果hash值不相同,则元素a添加成功。--->情况2
    38. 如果hash值相同,进而需要调用元素a所在类的equals()方法:
    39. equals()返回true,元素a添加失败
    40. equals()返回false,则元素a添加成功。--->情况3
    41. 对于添加成功的情况2和情况3而言:元素a与已经存在指定索引位置上数据以链表的方式存储。
    42. JDK 7:元素a放到数组中,指向原来的数据
    43. JDK 8:原来的元素在数组中,指向元素a
    44. 总结:七上八下
    45. HashSet底层:数组+链表的结构
    46. */
    47. @Test
    48. public void test1() {
    49. Set set = new HashSet();
    50. set.add(123);
    51. set.add(123);//重复了
    52. set.add(456);
    53. set.add("CC");
    54. set.add(new Person("Tom",12));
    55. set.add(new Person("Tom",12));//
    56. set.add("996");
    57. //遍历
    58. Iterator iterator = set.iterator();
    59. while (iterator.hasNext()){
    60. System.out.println(iterator.next());//无序的
    61. }
    62. //不可以用for遍历,因为Set没有索引值,没有get()方法!
    63. // for(int i = 0;i < set.size();i++){
    64. // System.out.println(set.get(i));
    65. // }
    66. }
    67. //LinkedHashSet的使用
    68. //LinkedHashSet作为HashSet的子类,在添加数据的同时,每个数据还维护了两个引用,记录此数据
    69. //前一个数据和后一个数据。
    70. //优点:对于频繁的遍历操作,LinkedHashSet效率要高于HashSet
    71. @Test
    72. public void test2() {
    73. Set set = new LinkedHashSet();
    74. set.add(123);
    75. set.add(123);//重复了
    76. set.add(456);
    77. set.add("CC");
    78. set.add(new Person("Tom",12));
    79. set.add(new Person("Tom",12));//
    80. set.add("996");
    81. //遍历
    82. Iterator iterator = set.iterator();
    83. while (iterator.hasNext()){
    84. System.out.println(iterator.next());//无序的
    85. }
    86. }
    87. @Test
    88. public void test3(){
    89. /*
    90. 1.向TreeSet中添加的数据,要求是相同类的对象。
    91. 2.两种排序方式:自然排序(实现Comparable接口) 和 定制排序(Comparator)
    92. 3.自然排序中,比较两个对象是否相同的标准为:comparableTo()返回0,不再是equals()。
    93. 4.定制排序中,比较两个对象是否相同的标准为:compare()返回0,不再是equals()。
    94. */
    95. TreeSet set = new TreeSet();
    96. //失败:不能添加不同类的对象
    97. // set.add(123);
    98. // set.add(123);//重复了
    99. // set.add(456);
    100. // set.add("CC");
    101. // set.add(new Person("Tom",12));
    102. // set.add(new Person("Tom",12));//
    103. // set.add("996");
    104. //举例一:
    105. // set.add(123);
    106. // set.add(456);
    107. // set.add(789);
    108. // set.add(996);
    109. // set.add(007);
    110. //
    111. // //遍历
    112. // Iterator iterator = set.iterator();
    113. // while (iterator.hasNext()){
    114. // System.out.println(iterator.next());//默认给排序了
    115. // }
    116. //举例二:String
    117. // set.add("小明");
    118. // set.add("BB");
    119. // set.add("笨蛋");
    120. // set.add("哈哈");
    121. // set.add("123");
    122. // set.add("AA");
    123. //
    124. //
    125. // //遍历
    126. // Iterator iterator = set.iterator();
    127. // while (iterator.hasNext()){
    128. // System.out.println(iterator.next());//默认给排序了
    129. // }
    130. //举例三;自定义类
    131. set.add(new Person("Tom",12));
    132. set.add(new Person("Jerry",8));
    133. set.add(new Person("Jack",18));
    134. set.add(new Person("Mike",15));
    135. set.add(new Person("Hans",21));
    136. set.add(new Person("Jack",8));
    137. //遍历
    138. Iterator iterator = set.iterator();
    139. while (iterator.hasNext()){
    140. System.out.println(iterator.next());//默认给排序了
    141. }
    142. }
    143. @Test
    144. public void test4(){
    145. Comparator com = new Comparator() {
    146. //按照年龄从小到大排列
    147. @Override
    148. public int compare(Object o1, Object o2) {
    149. if(o1 instanceof Person && o2 instanceof Person){
    150. Person p1 = (Person)o1;
    151. Person p2 = (Person)o2;
    152. return Integer.compare(p1.getAge(),p2.getAge());
    153. }else{
    154. throw new RuntimeException("输入的数据类型不匹配");
    155. }
    156. }
    157. };
    158. TreeSet set = new TreeSet(com);
    159. set.add(new Person("Tom",12));
    160. set.add(new Person("Jerry",8));
    161. set.add(new Person("Jack",18));
    162. set.add(new Person("Mike",15));
    163. set.add(new Person("Hans",21));
    164. set.add(new Person("Jack",8));
    165. //遍历
    166. Iterator iterator = set.iterator();
    167. while (iterator.hasNext()){
    168. System.out.println(iterator.next());//默认给排序了
    169. }
    170. }
    171. }