Java集合之Set

Set也是继承自Collection,Set也是集合的一种,同时Set不允许重复的元素存在。Set的实现类都是基于Map来实现的,其中HashSet是通过HashMap来实现的,TreeSet是通过TreeMap实现的。
Set架构:

(1)Set是继承于Collection的接口,它是一个不允许重复元素的集合。
(2)AbstractSet是一个抽象类,继承了AbstractCollection,AbstractCollection实现了Set中的绝大部分函数,为Set的实现类提供了便利。
(3)HashSet和TreeSet是Set的两个实现类。HashSet依赖于HashMap,实际上是通过HashMap来实现的,HashSet中的元素是无序的。TreeSet依赖于TreeMap,实际上是通过TreeMap实现的,TreeSet中的元素是有序的。
基于Java8的AbstractCollection源码:
[java]  view plain  copy
  1. public abstract class AbstractCollection<E> implements Collection<E> {  
  2.     protected AbstractCollection() {//构造函数  
  3.     }  
  4.     public abstract Iterator<E> iterator();//迭代器  
  5.   
  6.     public abstract int size();//集合大小  
  7.   
  8.     public boolean isEmpty() {//集合是否为空  
  9.         return size() == 0;  
  10.     }  
  11.     public boolean contains(Object o) {//判断是否包含某个元素,通过迭代遍历的方式  
  12.         Iterator<E> it = iterator();  
  13.         if (o==null) {  
  14.             while (it.hasNext())  
  15.                 if (it.next()==null)  
  16.                     return true;  
  17.         } else {  
  18.             while (it.hasNext())  
  19.                 if (o.equals(it.next()))  
  20.                     return true;  
  21.         }  
  22.         return false;  
  23.     }  
  24.     public Object[] toArray() {//生成数组  
  25.         // Estimate size of array; be prepared to see more or fewer elements  
  26.         Object[] r = new Object[size()];  
  27.         Iterator<E> it = iterator();  
  28.         for (int i = 0; i < r.length; i++) {  
  29.             if (! it.hasNext()) // fewer elements than expected  
  30.                 return Arrays.copyOf(r, i);  
  31.             r[i] = it.next();  
  32.         }  
  33.         return it.hasNext() ? finishToArray(r, it) : r;  
  34.     }  
  35.     @SuppressWarnings("unchecked")  
  36.     public <T> T[] toArray(T[] a) {//泛型方式生成数组  
  37.         // Estimate size of array; be prepared to see more or fewer elements  
  38.         int size = size();  
  39.         T[] r = a.length >= size ? a :  
  40.                 (T[])java.lang.reflect.Array  
  41.                         .newInstance(a.getClass().getComponentType(), size);  
  42.         Iterator<E> it = iterator();  
  43.         for (int i = 0; i < r.length; i++) {  
  44.             if (! it.hasNext()) { // fewer elements than expected  
  45.                 if (a == r) {  
  46.                     r[i] = null// null-terminate  
  47.                 } else if (a.length < i) {  
  48.                     return Arrays.copyOf(r, i);  
  49.                 } else {  
  50.                     System.arraycopy(r, 0, a, 0, i);  
  51.                     if (a.length > i) {  
  52.                         a[i] = null;  
  53.                     }  
  54.                 }  
  55.                 return a;  
  56.             }  
  57.             r[i] = (T)it.next();  
  58.         }  
  59.         // more elements than expected  
  60.         return it.hasNext() ? finishToArray(r, it) : r;  
  61.     }  
  62.     private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;  
  63.     @SuppressWarnings("unchecked")  
  64.     private static <T> T[] finishToArray(T[] r, Iterator<?> it) {  
  65.         int i = r.length;  
  66.         while (it.hasNext()) {  
  67.             int cap = r.length;  
  68.             if (i == cap) {  
  69.                 int newCap = cap + (cap >> 1) + 1;  
  70.                 // overflow-conscious code  
  71.                 if (newCap - MAX_ARRAY_SIZE > 0)  
  72.                     newCap = hugeCapacity(cap + 1);  
  73.                 r = Arrays.copyOf(r, newCap);  
  74.             }  
  75.             r[i++] = (T)it.next();  
  76.         }  
  77.         // trim if overallocated  
  78.         return (i == r.length) ? r : Arrays.copyOf(r, i);  
  79.     }  
  80.     //对输入的minCapacity判断最大容量  
  81.     private static int hugeCapacity(int minCapacity) {  
  82.         if (minCapacity < 0// overflow  
  83.             throw new OutOfMemoryError  
  84.                     ("Required array size too large");  
  85.         return (minCapacity > MAX_ARRAY_SIZE) ?  
  86.                 Integer.MAX_VALUE :  
  87.                 MAX_ARRAY_SIZE;  
  88.     }  
  89.     //添加对象  
  90.     public boolean add(E e) {  
  91.         throw new UnsupportedOperationException();  
  92.     }  
  93.     //通过迭代查找,删除对象  
  94.     public boolean remove(Object o) {  
  95.         Iterator<E> it = iterator();  
  96.         if (o==null) {  
  97.             while (it.hasNext()) {  
  98.                 if (it.next()==null) {  
  99.                     it.remove();  
  100.                     return true;  
  101.                 }  
  102.             }  
  103.         } else {  
  104.             while (it.hasNext()) {  
  105.                 if (o.equals(it.next())) {  
  106.                     it.remove();  
  107.                     return true;  
  108.                 }  
  109.             }  
  110.         }  
  111.         return false;  
  112.     }  
  113.     //判断集合C中的元素是否都存在  
  114.     public boolean containsAll(Collection<?> c) {  
  115.         for (Object e : c)  
  116.             if (!contains(e))  
  117.                 return false;  
  118.         return true;  
  119.     }  
  120.     //将集合c中的元素添加  
  121.     public boolean addAll(Collection<? extends E> c) {  
  122.         boolean modified = false;  
  123.         for (E e : c)  
  124.             if (add(e))  
  125.                 modified = true;  
  126.         return modified;  
  127.     }  
  128.     //删除掉集合c中在此集合中的元素  
  129.     public boolean removeAll(Collection<?> c) {  
  130.         Objects.requireNonNull(c);  
  131.         boolean modified = false;  
  132.         Iterator<?> it = iterator();  
  133.         while (it.hasNext()) {  
  134.             if (c.contains(it.next())) {  
  135.                 it.remove();  
  136.                 modified = true;  
  137.             }  
  138.         }  
  139.         return modified;  
  140.     }  
  141.     //删除掉此集合中在c中不存在的对象  
  142.     public boolean retainAll(Collection<?> c) {  
  143.         Objects.requireNonNull(c);  
  144.         boolean modified = false;  
  145.         Iterator<E> it = iterator();  
  146.         while (it.hasNext()) {  
  147.             if (!c.contains(it.next())) {  
  148.                 it.remove();  
  149.                 modified = true;  
  150.             }  
  151.         }  
  152.         return modified;  
  153.     }  
  154.     //清空集合  
  155.     public void clear() {  
  156.         Iterator<E> it = iterator();  
  157.         while (it.hasNext()) {  
  158.             it.next();  
  159.             it.remove();  
  160.         }  
  161.     }  
  162.     //通过StringBuilder生成string  
  163.     public String toString() {  
  164.         Iterator<E> it = iterator();  
  165.         if (! it.hasNext())  
  166.             return "[]";  
  167.   
  168.         StringBuilder sb = new StringBuilder();  
  169.         sb.append('[');  
  170.         for (;;) {  
  171.             E e = it.next();  
  172.             sb.append(e == this ? "(this Collection)" : e);  
  173.             if (! it.hasNext())  
  174.                 return sb.append(']').toString();  
  175.             sb.append(',').append(' ');  
  176.         }  
  177.     }  
  178.   
  179. }  


基于Java8的AbstractSet源代码:
[java]  view plain  copy
  1. public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E> {  
  2.   
  3.     protected AbstractSet() {  
  4.     }  
  5.     public boolean equals(Object o) {//判断两个集合是否相同  
  6.         if (o == this)  
  7.             return true;  
  8.   
  9.         if (!(o instanceof Set))  
  10.             return false;  
  11.         Collection<?> c = (Collection<?>) o;  
  12.         if (c.size() != size())  
  13.             return false;  
  14.         try {  
  15.             return containsAll(c);  
  16.         } catch (ClassCastException unused)   {  
  17.             return false;  
  18.         } catch (NullPointerException unused) {  
  19.             return false;  
  20.         }  
  21.     }  
  22.     //计算hashCode  
  23.     public int hashCode() {  
  24.         int h = 0;  
  25.         Iterator<E> i = iterator();  
  26.         while (i.hasNext()) {  
  27.             E obj = i.next();  
  28.             if (obj != null)  
  29.                 h += obj.hashCode();  
  30.         }  
  31.         return h;  
  32.     }  
  33.     //删除此集合中与c中相同的对象  
  34.     public boolean removeAll(Collection<?> c) {  
  35.         Objects.requireNonNull(c);  
  36.         boolean modified = false;  
  37.   
  38.         if (size() > c.size()) {  
  39.             for (Iterator<?> i = c.iterator(); i.hasNext(); )  
  40.                 modified |= remove(i.next());  
  41.         } else {  
  42.             for (Iterator<?> i = iterator(); i.hasNext(); ) {  
  43.                 if (c.contains(i.next())) {  
  44.                     i.remove();  
  45.                     modified = true;  
  46.                 }  
  47.             }  
  48.         }  
  49.         return modified;  
  50.     }  
  51.   
  52. }  


基于Java8的SortSet源码:

public interface SortedSet<E> extends Set<E> {
    Comparator<? super E> comparator();
    SortedSet<E> subSet(E fromElement, E toElement);
    SortedSet<E> headSet(E toElement);
    SortedSet<E> tailSet(E fromElement);
    E first();
    E last();
    @Override
    default Spliterator<E> spliterator() {
        return new Spliterators.IteratorSpliterator<E>(
                this, Spliterator.DISTINCT | Spliterator.SORTED | Spliterator.ORDERED) {
            @Override
            public Comparator<? super E> getComparator() {
                return SortedSet.this.comparator();
            }
        };
    }
}

基于Java8的NavigableSet源码:

public interface NavigableSet<E> extends SortedSet<E> {
    E lower(E e);
    E floor(E e);
    E ceiling(E e);
    E higher(E e);
    E pollFirst();
    E pollLast();
    Iterator<E> iterator();
    NavigableSet<E> descendingSet();
    Iterator<E> descendingIterator();
    NavigableSet<E> subSet(E fromElement, boolean fromInclusive,
                           E toElement,   boolean toInclusive);
    NavigableSet<E> headSet(E toElement, boolean inclusive);
    NavigableSet<E> tailSet(E fromElement, boolean inclusive);
    SortedSet<E> subSet(E fromElement, E toElement);
    SortedSet<E> headSet(E toElement);
    SortedSet<E> tailSet(E fromElement);
}
基于Java8的Set源码:
[java]  view plain  copy
  1. public interface Set<E> extends Collection<E> {  
  2. int size(); //大小  
  3. boolean isEmpty();//是否为空  
  4. boolean contains(Object o); //是否包含某个对象  
  5. Iterator<E> iterator(); //生成迭代器  
  6. Object[] toArray(); //返回Object数组  
  7. <T> T[] toArray(T[] a); //返回泛型数组  
  8. boolean add(E e); //向set中添加元素  
  9. boolean remove(Object o); //从set中删除某个元素  
  10. boolean containsAll(Collection<?> c); //某个Collection是否都包含在此lset中  
  11. boolean addAll(Collection<? extends E> c); //将某个Collection追加到此set中  
  12. boolean retainAll(Collection<?> c); //删除不存在于Collection中的set中的元素  
  13. boolean removeAll(Collection<?> c); //删除包含在此Collection中的元素  
  14. void clear(); //清空set  
  15. boolean equals(Object o);//判断两个set是否相同  
  16. int hashCode(); //计算set的hashCode  
  17. @Override  
  18. default Spliterator<E> spliterator() {  
  19. return Spliterators.spliterator(this, Spliterator.DISTINCT);  
  20. }  
  21. }  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: HashSetJava的一种集合类型,它继承自AbstractSet类,并且实现了Set接口。它是基于哈希表实现的,可以存储不重复的元素。HashSet的实现依赖于它存储的元素的hashCode()方法和equals()方法。 当一个元素被添加到HashSet时,HashSet会首先调用该元素的hashCode()方法,然后根据hashCode()方法的返回值,将该元素放入相应的桶(bucket)。如果桶已经存在该元素,则HashSet会调用该元素的equals()方法与桶的元素进行比较,如果equals()方法返回true,表示这两个元素是相同的,HashSet就不会再次添加该元素。如果equals()方法返回false,则HashSet会将该元素添加到桶。 由于HashSet是基于哈希表实现的,所以它的查询速度非常快,平均时间复杂度为O(1)。但是,HashSet的迭代顺序并不是按照元素的插入顺序来排列的,而是按照元素的哈希值来排列的。 ### 回答2: HashsetJava集合框架的一种集合类,它基于哈希表实现,也称为哈希集。与List相比,Hashset集合的元素不是有序的,而是无序的。而且,Hashset集合的元素是唯一的,即集合不存在相同的元素。 哈希表是哈希算法的一种典型应用,Hashset底层通过哈希表来实现。具体来说,当往Hashset添加元素时,Hashset会先对这个元素进行哈希运算,根据哈希算法得到一个唯一的哈希值。这个哈希值会被作为元素在哈希表的位置来存储。如果这个位置上已经有其它元素了,那么Hashset会比较这个元素和已存在元素的哈希值和equals()方法,若哈希值相同且equals()方法返回true,则认为这个元素已经存在于集合,不再添加;否则,哈希表会使用开链的方式在这个位置上存储多个元素。 由于哈希表是一种效率比较高的数据结构,因此Hashset在添加、删除和查找元素时的速度都比较快。但是,由于哈希表的实现依赖于哈希算法的效率,哈希表在存储元素时可能会发生哈希冲突,导致性能下降。通常情况下,为了避免哈希冲突的发生,我们需要根据实际情况来选择合适的哈希函数或者调整哈希表的大小。 总之,Hashset作为Java集合框架的一种集合类,提供了高效的添加、删除和查找元素的操作,同时也会遇到哈希冲突的问题需要注意。 ### 回答3: Java集合Set是一个不允许有重复元素的集合。而HashSet则是Set接口的一种具体实现,底层实现采用的是哈希表,因此插入、删除和查找的时间复杂度均为O(1)。 HashSet的元素并没有被排序,因为它是基于哈希表实现的。哈希表通过将元素的关键字映射到数组的索引位置来实现快速访问,即使将大量元素存储在哈希表,访问元素时仍然能够在常数时间内完成。 HashSet元素是根据它们的哈希码值存储的,因此先要实现hashCode()方法。此外,还要实现equals()方法来确保HashSet能够正确地判断两个元素是否相等。当两个元素的hashCode()值相等并且equals()方法返回true时,HashSet将认为这两个元素是相同的,不会插入重复元素。 HashSet的迭代器是一种散列码的迭代器,它返回的元素不会保证按照任何特定的顺序排列。当遍历HashSet时,不能保证元素的迭代顺序与元素插入的顺序相同。 在使用HashSet时需要注意,由于哈希表的实现,HashSet不是线程安全的,如果多个线程同时访问HashSet,可能会导致意外的结果,需要进行同步处理。 总之,HashSet是一个高效的集合实现,它允许快速的插入、删除和查找。如果你需要一个不允许重复元素的无序集合,并且希望能够快速地访问和修改元素,那么HashSet是一个不错的选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值