Set集合类似于一个罐子,程序可以依次把多个对象“丢进”Set集合,而Set集合通常不能记住元素的添加顺序。
Set集合不允许包含相同的元素,如果试图把两个相同的元素加入同一个Set集合中,则添加操作失败,add()方法返回 false,且新元素不会被加入。
一、HashSet类
HashSet类是Set接口的典型实现类,大多数时候使用Set集合时就是使用这个实现类。 HashSet类按Hash算法来存储集合中的元素,因此具有很好的存取和查找性能。
HashSet类具有以下特点:
• 不能保证元素的排列顺序,顺序可能与添加顺序不同,顺序也有可能发生变化。
• HashSet不是同步的(不是线程安全的),如果多个线程同时访问一个 HashSet,假设有两个或者两个以上线程同时修改了 HashSet集合时,则必须通过代码来保证其同步。
• 集合元素值可以是null,但只能放入一个null。
当向 HashSet集合中存入一个元素时, HashSet会调用该对象的 hashCode()方法来得到该对象的hashCode值,然后根据该hashCode值决定该对象在HashSet中的存储位置。如果有两个元素通过 equals方法比较返回true,但它们的hashCode()方法返回值不相等, HashSet将会把它们存储在不同的位置,依然可以添加成功。
HashSet判断元素是否相等的依据:对象的equals()比较返回false;且hashCode值不相等,判断两个元素不相等;
1. import java.util.ArrayList;
2. import java.util.HashSet;
3. import java.util.Iterator;
4. import java.util.List;
5. /**
6. * set 无序 不允许重复元素
7. * HashSet 可以放入null,但只能放入一个null
8. * @author sxj
9. */
10. public class HashSetDemo {
11. public static void main(String[] args) {
12. HashSet<String> set = new HashSet<>();
13.
14. // 添加元素
15. set.add("B");
16. set.add("A");
17. set.add("D");
18. set.add("C");
19. set.add("A");
20. set.add("F");
21. set.add("G");
22. set.add("I");
23. set.add("I");
24. set.add("I");
25. set.add("I");
26. set.add(null);//可以放入null,但只能放入一个null
27.
28. // 移除
29. //set.remove("I");
30.
31. List<String> list = new ArrayList<>();
32. list.add("F");
33. list.add("G");
34. set.removeAll(list);
35.
36. //
37.
38. // 输出set
39. System.out.println(set.toString());
40. // 遍历
41. System.out.println("foreach遍历:");
42. for (String string : set) {
43. System.out.print(string + " ");
44. }
45. // 迭代器遍历
46. System.out.println("\nIterator 迭代器 while:");
47. Iterator<String> iterator = set.iterator();
48. while (iterator.hasNext()) {
49. System.out.print(iterator.next() + " ");
50. }
51. System.out.println("\nIterator 迭代器 for:");
52. for (Iterator<String> iterator2 = set.iterator(); iterator2.hasNext();) {
53. String string = (String) iterator2.next();
54. System.out.print(string + " ");
55. }
56.
57. // 获取元素个数
58. System.out.println("HashSet的元素格个数:" + set.size());
59. // HashSet中是否包含某个元素
60. System.out.println("HashSet中是否包含某个元素:" + set.contains("F"));
61.
62. //清空set
63. set.clear();
64.
65. //
66. System.out.println("set是否为空"+set.isEmpty());
67. }
68. }
二、LinkedHashSet类
HashSet类还有一个子类 LinkedHashSet, LinkedHashSet集合也是根据元素的 hashCode值来决定元素的存储位置,但它同时使用链表维护元素的次序,这样使得元素看起来是以插入的顺序保存的。也就是说,当遍历 LinkedhashSet集合里的元素时, LinkedHashSet将会按元素的添加顺序来访问集合里的元素。
LinkedHashSet需要维护元素的插入顺序,因此性能略低于 HashSet的性能,但在迭代访问Set里的全部元素时将有很好的性能,因为它以链表来维护内部顺序。
示例代码:
1. import java.util.Iterator;
2. import java.util.LinkedHashSet;
3.
4. public class LinkedHashSetDemo {
5. public static void main(String[] args) {
6. LinkedHashSet<String> set = new LinkedHashSet<>();
7.
8. // 添加元素
9. set.add("B");
10. set.add("A");
11. set.add("D");
12. set.add("C");
13. set.add("A");
14. set.add("F");
15. set.add("G");
16. set.add("I");
17. set.add(null);// 可以放入null,但只能放入一个null
18.
19. // 迭代器遍历
20. System.out.println("Iterator 迭代器 while:");
21. Iterator<String> iterator = set.iterator();
22. while (iterator.hasNext()) {
23. System.out.print(iterator.next() + " ");
24. }
25. }
26. }
三、TreeSet类
TreeSet是 SortedSet接口的实现类,正如 SortedSet名字所暗示的, TreeSet可以确保集合元素处于排序状态。与 Set集合相比,TreeSet还提供了如下几个额外的方法。
示例代码:
1. import java.util.Iterator;
2. import java.util.SortedSet;
3. import java.util.TreeSet;
4.
5. /**
6. * TreeSet不允许放入null值
7. * @author sxj
8. *
9. */
10. public class TreeSetDemo {
11. public static void main(String[] args) {
12. TreeSet<String> set = new TreeSet<>();
13.
14. // 添加元素
15. set.add("B");
16. set.add("A");
17. set.add("D");
18. set.add("C");
19. set.add("A");
20. set.add("F");
21. set.add("G");
22. set.add("H");
23. set.add("I");
24. set.add("I");
25. set.add("I");
26.
27. // 移除
28. // set.remove("I");
29.
30. // List<String> list = new ArrayList<>();
31. // list.add("F");
32. // list.add("G");
33. // set.removeAll(list);
34.
35. //
36.
37. // 输出set
38. System.out.println(set.toString());
39. // 遍历
40. System.out.println("foreach遍历:");
41. for (String string : set) {
42. System.out.print(string + " ");
43. }
44. // 迭代器遍历
45. System.out.println("\nIterator 迭代器 while:");
46. Iterator<String> iterator = set.iterator();
47. while (iterator.hasNext()) {
48. System.out.print(iterator.next() + " ");
49. }
50. System.out.println("\nIterator 迭代器 for:");
51. for (Iterator<String> iterator2 = set.iterator(); iterator2.hasNext();) {
52. String string = (String) iterator2.next();
53. System.out.print(string + " ");
54. }
55.
56. // 获取元素个数
57. System.out.println("HashSet的元素格个数:" + set.size());
58. // HashSet中是否包含某个元素
59. System.out.println("HashSet中是否包含某个元素:" + set.contains("F"));
60.
61. // 清空set
62. //set.clear();
63.
64. //
65. System.out.println("set是否为空" + set.isEmpty());
66.
67. String first = set.first();
68. System.out.println("第一个元素:" + first);
69. String last = set.last();
70. System.out.println("最后一个元素:" + last);
71. String str1 = set.lower(last);
72. System.out.println("最后一个元素的前一个元素:" + str1);
73. String str2 = set.higher(first);
74. System.out.println("第一个元素的后一个元素:" + str2);
75. String str3 = set.floor("H");
76. System.out.println("集合中小于或者等于给定元素的最大元素:" + str3);
77. System.out.println("===============");
78.
79. //
80. SortedSet<String> sortedSet1=set.headSet("F");
81. System.out.println(sortedSet1);
82. SortedSet<String> sortedSet2=set.tailSet("F");
83. System.out.println(sortedSet2);
84. SortedSet<String> sortedSet3=set.subSet("B", "F"); //[B,F)
85. System.out.println(sortedSet3);
86.
87. System.out.println("===============");
88. System.out.println(set);
89. //移除第一个对象,并返回该对象
90. System.out.println(set.pollFirst());
91. //移除最后一个对象,并返回该对象
92. System.out.println(set.pollLast());
93. System.out.println(set);
94. }
95. }
由于TreeSet是有序的,也支持Comparable和Comparator两种排序方式
TreeSet Comparable排序示例代码:
1. import java.util.Iterator;
2. import java.util.Set;
3. import java.util.TreeSet;
4.
5. public class TreeSetDemo1 {
6. public static void main(String[] args) {
7. Set<PersonComparable> persons = new TreeSet<PersonComparable>();
8.
9. persons.add(new PersonComparable("小A", 35));
10. persons.add(new PersonComparable("小B", 25));
11. persons.add(new PersonComparable("小C", 25));
12. persons.add(new PersonComparable("小D", 12));
13. persons.add(new PersonComparable("小X", 33));
14. persons.add(new PersonComparable("小M", 33));
15. persons.add(new PersonComparable("小E", 33));
16.
17. Iterator<PersonComparable> it = persons.iterator();
18. while (it.hasNext()) {
19. PersonComparable person = (PersonComparable) it.next();
20. System.out.println(person.getName()+"\t"+person.getAge());
21. }
22.
23. }
24. }
25.
26. /**
27. * Comparable 用来实现集合中元素的比较、排序的
28. * Comparable 是在集合内部定义的方法实现的排序
29. * @author sxj
30. *
31. */
32. class PersonComparable implements Comparable<PersonComparable> {
33. private int age;
34. private String name;
35.
36. public PersonComparable() {
37.
38. }
39.
40. public PersonComparable(String name, int age) {
41. this.age = age;
42. this.name = name;
43. }
44.
45. public int getAge() {
46. return age;
47. }
48.
49. public void setAge(int age) {
50. this.age = age;
51. }
52.
53. public String getName() {
54. return name;
55. }
56.
57. public void setName(String name) {
58. this.name = name;
59. }
60.
61. @Override
62. public int compareTo(PersonComparable o) {
63. // TODO Auto-generated method stub
64. // 从小到大 :this.age-o.age
65. // 从大到小:o.age-this.age
66. if (o.age != this.age) {
67. return this.age-o.age;
68. } else {
69. return this.name.compareTo(o.name);
70. }
71.
72. }
73. }
TreeSet Comparator排序示例代码:
1. import java.util.Comparator;
2. import java.util.Iterator;
3. import java.util.Set;
4. import java.util.TreeSet;
5.
6. public class TreeSetDemo2 {
7. public static void main(String[] args) {
8. Set<PersonComparator> persons = new TreeSet<PersonComparator>(new Comparator<PersonComparator>() {
9. @Override
10. public int compare(PersonComparator o1, PersonComparator o2) {
11. /**
12. * 从小到大:o1-o2 从大到小:o2-o1
13. */
14. //改进比较方法:先根据年龄排序,如果年龄一样,根据姓名排序
15. if (o1.getAge() != o2.getAge()) {
16. return o1.getAge() - o2.getAge();
17. } else {
18. return o2.getName().compareTo(o1.getName());
19. }
20. }
21. });
22.
23. persons.add(new PersonComparator("小A", 35));
24. persons.add(new PersonComparator("小B", 25));
25. persons.add(new PersonComparator("小C", 25));
26. persons.add(new PersonComparator("小D", 12));
27. persons.add(new PersonComparator("小X", 33));
28. persons.add(new PersonComparator("小M", 33));
29. persons.add(new PersonComparator("小E", 33));
30.
31. Iterator<PersonComparator> it = persons.iterator();
32. while (it.hasNext()) {
33. PersonComparator person = (PersonComparator) it.next();
34. System.out.println(person.getName()+"\t"+person.getAge());
35. }
36. }
37. }
38.
39. class PersonComparator {
40. private int age;
41. private String name;
42.
43. public PersonComparator() {
44.
45. }
46.
47. public PersonComparator(String name, int age) {
48. this.name = name;
49. this.age = age;
50. }
51.
52. public int getAge() {
53. return age;
54. }
55.
56. public void setAge(int age) {
57. this.age = age;
58. }
59.
60. public String getName() {
61. return name;
62. }
63.
64. public void setName(String name) {
65. this.name = name;
66. }
67. }