类关系图

Set - 图1

功能介绍

包路径java.util

功能描述:Set 继承自Collection接口,只是行为上不同,Set 不保存重复的元素**。Set集合的实现类可说是基于Map集合去写的。通过内部封装Map集合来实现的比如HashSet内部封装了HashMap

Set 接口存储一组唯一,无序的对象。

特点插入无序,不可指定位置访问。

源码解析

Set

  1. package java.util;
  2. /**
  3. *
  4. * @param <E> the type of elements maintained by this set
  5. *
  6. * @author Josh Bloch
  7. * @author Neal Gafter
  8. * @see Collection
  9. * @see List
  10. * @see SortedSet
  11. * @see HashSet
  12. * @see TreeSet
  13. * @see AbstractSet
  14. * @see Collections#singleton(java.lang.Object)
  15. * @see Collections#EMPTY_SET
  16. * @since 1.2
  17. */
  18. public interface Set<E> extends Collection<E> {
  19. // Query Operations
  20. /**
  21. * 获取集合元素数量
  22. * @return the number of elements in this set (its cardinality)
  23. */
  24. int size();
  25. /**
  26. * 判断集合是否为空
  27. * @return <tt>true</tt> if this set contains no elements
  28. */
  29. boolean isEmpty();
  30. /**
  31. * 判断集合内是否存在目标元素
  32. * @param o element whose presence in this set is to be tested
  33. * @return <tt>true</tt> if this set contains the specified element
  34. */
  35. boolean contains(Object o);
  36. /**
  37. * 返回迭代器
  38. * @return an iterator over the elements in this set
  39. */
  40. Iterator<E> iterator();
  41. /**
  42. * 将集合转为数组返回
  43. * @return an array containing all the elements in this set
  44. */
  45. Object[] toArray();
  46. /**
  47. * 将集合转为目标类型的数组返回
  48. * @param a the array into which the elements of this set are to be
  49. * stored, if it is big enough; otherwise, a new array of the same
  50. * runtime type is allocated for this purpose.
  51. * @return an array containing all the elements in this set
  52. */
  53. <T> T[] toArray(T[] a);
  54. // Modification Operations
  55. /**
  56. * 添加元素
  57. * @param e element to be added to this set
  58. * @return <tt>true</tt> if this set did not already contain the specified
  59. * element
  60. */
  61. boolean add(E e);
  62. /**
  63. * 从集合中移除元素
  64. * @param o object to be removed from this set, if present
  65. * @return <tt>true</tt> if this set contained the specified element
  66. */
  67. boolean remove(Object o);
  68. // Bulk Operations
  69. /**
  70. * 判断是否存在传入集合的所有元素(交集)
  71. * @param c collection to be checked for containment in this set
  72. * @return <tt>true</tt> if this set contains all of the elements of the
  73. * specified collection
  74. */
  75. boolean containsAll(Collection<?> c);
  76. /**
  77. * 添加传入集合的所有元素
  78. * @param c collection containing elements to be added to this set
  79. * @return <tt>true</tt> if this set changed as a result of the call
  80. * @see #add(Object)
  81. */
  82. boolean addAll(Collection<? extends E> c);
  83. /**
  84. * 仅保留传入集合里存在的元素(求交集)
  85. * @param c collection containing elements to be retained in this set
  86. * @return <tt>true</tt> if this set changed as a result of the call
  87. * @see #remove(Object)
  88. */
  89. boolean retainAll(Collection<?> c);
  90. /**
  91. * 仅移除传入集合的所有元素
  92. * @param c collection containing elements to be removed from this set
  93. * @return <tt>true</tt> if this set changed as a result of the call
  94. * @see #remove(Object)
  95. * @see #contains(Object)
  96. */
  97. boolean removeAll(Collection<?> c);
  98. /**
  99. * 清空集合
  100. */
  101. void clear();
  102. // Comparison and hashing
  103. /**
  104. * 判断集合是否相等(集合内所有元素相等则为相等)
  105. * @param o object to be compared for equality with this set
  106. * @return <tt>true</tt> if the specified object is equal to this set
  107. */
  108. boolean equals(Object o);
  109. /**
  110. *
  111. * @return the hash code value for this set
  112. * @see Object#equals(Object)
  113. * @see Set#equals(Object)
  114. */
  115. int hashCode();
  116. /**
  117. * 返回切割器
  118. * @return a {@code Spliterator} over the elements in this set
  119. * @since 1.8
  120. */
  121. @Override
  122. default Spliterator<E> spliterator() {
  123. return Spliterators.spliterator(this, Spliterator.DISTINCT);
  124. }
  125. }

AbstractSet

AbstractSet是一个抽象类,实现了Set接口,同时继承了AbstractCollection抽象类

  1. package java.util;
  2. /**
  3. *
  4. * @author Josh Bloch
  5. * @author Neal Gafter
  6. * @see Collection
  7. * @see AbstractCollection
  8. * @see Set
  9. * @since 1.2
  10. */
  11. public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E> {
  12. /**
  13. * Sole constructor. (For invocation by subclass constructors, typically
  14. * implicit.)
  15. */
  16. protected AbstractSet() {
  17. }
  18. // Comparison and hashing
  19. /**
  20. * 比较两个集合是否相等
  21. * @param o object to be compared for equality with this set
  22. * @return <tt>true</tt> if the specified object is equal to this set
  23. */
  24. public boolean equals(Object o) {
  25. if (o == this)
  26. return true;
  27. if (!(o instanceof Set))
  28. return false;
  29. Collection<?> c = (Collection<?>) o;
  30. if (c.size() != size())
  31. return false;
  32. try {
  33. // 是否全部存在
  34. return containsAll(c);
  35. } catch (ClassCastException unused) {
  36. return false;
  37. } catch (NullPointerException unused) {
  38. return false;
  39. }
  40. }
  41. /**
  42. *
  43. * @return the hash code value for this set
  44. * @see Object#equals(Object)
  45. * @see Set#equals(Object)
  46. */
  47. public int hashCode() {
  48. int h = 0;
  49. Iterator<E> i = iterator();
  50. while (i.hasNext()) {
  51. E obj = i.next();
  52. if (obj != null)
  53. h += obj.hashCode();
  54. }
  55. return h;
  56. }
  57. /**
  58. * 从当前集合中移除传入集合包含的所有元素
  59. * @param c collection containing elements to be removed from this set
  60. * @return <tt>true</tt> if this set changed as a result of the call
  61. * @see #remove(Object)
  62. * @see #contains(Object)
  63. */
  64. public boolean removeAll(Collection<?> c) {
  65. Objects.requireNonNull(c);
  66. boolean modified = false;
  67. // 如果当前集合元素比传入集合元素多
  68. if (size() > c.size()) {
  69. // 迭代传入集合并从当前集合移除
  70. for (Iterator<?> i = c.iterator(); i.hasNext(); )
  71. modified |= remove(i.next());
  72. } else {
  73. // 迭代当前集合
  74. for (Iterator<?> i = iterator(); i.hasNext(); ) {
  75. if (c.contains(i.next())) {
  76. i.remove();
  77. modified = true;
  78. }
  79. }
  80. }
  81. return modified;
  82. }
  83. }

简单使用

  1. public class SetCode {
  2. public static void main(String[] args) {
  3. commonExample();
  4. }
  5. public static void commonExample(){
  6. Set<Integer> mySet = new HashSet<>();
  7. for(int i=0;i<20;i++){
  8. mySet.add(i);
  9. }
  10. System.out.println("mySet = "+mySet);
  11. System.out.println("mySet.size() = "+mySet.size());
  12. Set<Integer> subSet = new HashSet<>();
  13. for(int i=0;i<10;i++){
  14. subSet.add(i);
  15. }
  16. System.out.println("subSet = "+subSet);
  17. System.out.println("mySet.containsAll(subSet) = "+mySet.containsAll(subSet));
  18. mySet.removeAll(subSet);
  19. System.out.println("mySet = "+mySet);
  20. }
  21. }

输出:

mySet = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

mySet.size() = 20

subSet = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

mySet.containsAll(subSet) = true

mySet = [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

总结

1、Set 继承自Collection接口,只是行为上不同,Set 不保存重复的元素。Set集合的实现类可说是基于Map集合去写的。通过内部封装Map集合来实现的比如HashSet内部封装了HashMap

2、Set 接口存储一组唯一,无序的对象。

3、Set插入无序,不可指定位置访问。

思考

Set和List的区别

    1. Set 接口实例存储的是无序的,不重复的数据。List 接口实例存储的是有序的,可以重复的元素。
    1. Set检索效率低下,删除和插入效率高,插入和删除不会引起元素位置改变 <实现类有HashSet,TreeSet>。
    1. List和数组类似,可以动态增长,根据实际存储的数据的长度自动增长List的长度。查找元素效率高,插入删除效率低,因为会引起其他元素位置改变 <实现类有ArrayList,LinkedList,Vector> 。