zoukankan      html  css  js  c++  java
  • java容器类3:set/HastSet/MapSet深入解读

    介绍

    Set:集合,是一个不包含重复数据的集合。(A collection that contains no duplicate elements. )

    set中最多包含一个null元素,否者包含了两个相同的元素,不符合定义。

    上一篇学习了Java中的容器类的一些基础接口,以及Collection接口三大分支中的List分支(ArrayList以及LinkedList)。这一篇文章将讲解Collection三大分支(List、Set、Queue)中的Set分支,以及衍生出来的子类。

    java容器类分析:Collection,List,ArrayList,LinkedList深入解读

    Set接口的总的集成关系如下图:

    未命名文件 (2)


    Set接口

    public interface Set<E> extends Collection<E>

    查看Set的源码可以发现,Set中的接口函数和Collection完全相同,并没有添加任何新的接口。只是子类在实现这些接口的时候需要考虑,Set中不能有重复的元素这一原则。接口中的函数及描述可查看上一篇博客。


    AbstractSet抽象类

    和AbstractList及AbstractCollection的作用相似,AbstractSet类作为一个抽象类,实现了Set接口中的部分函数,减少后续Set子类的实现工作。

    public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E>

    具体该抽象类实现了Set中的如下几个接口:
     public boolean equals(Object o) {
            if (o == this)
                return true;
    
            if (!(o instanceof Set))
                return false;
            Collection<?> c = (Collection<?>) o;
            if (c.size() != size())
                return false;
            try {
                
    return containsAll(c);
            } catch (ClassCastException unused)   {
                return false;
            } catch (NullPointerException unused) {
                return false;
            }
        }

    hashCode():Set的hash值等于将Set中所有元素的hash值相加,这就保证了if(set1.equals(set2)) 那么set1.hashCode()== set2.hashCode()。

    public int hashCode() {
            int h = 0;
            Iterator<E> i = iterator();
            while (i.hasNext()) {
                E obj = i.next();
                if (obj != null)
                    h += obj.hashCode();
            }
            return h;
        }

    removeAll(): 移除c与当前Set的交集,返回值代表是否有元素从当前Set中移除,交集为空返回false否则返回true。

    public boolean removeAll(Collection<?> c) {
            Objects.requireNonNull(c);
            boolean modified = false;
    
            if (size() > c.size()) {
                for (Iterator<?> i = c.iterator(); i.hasNext(); )
                    modified |= remove(i.next());
            } else {
                for (Iterator<?> i = iterator(); i.hasNext(); ) {
                    if (c.contains(i.next())) {
                        i.remove();
                        modified = true;
                    }
                }
            }
            return modified;
        }

    SortedSet


    public interface SortedSet<E> extends Set<E>

    
    
    public interface SortedSet<E> extends Set<E> {//经过某种排序的set       JDK1.7   java.util  
    
        Comparator<? super E> comparator();//返回对此 set中的元素进行排序的比较器  
        SortedSet<E> subSet(E fromElement, E toElement);//返回此 set的部分视图,其元素从 fromElement(包括)到 toElement(不包括)。(  
        SortedSet<E> headSet(E toElement);//返回此 set 的部分视图,其元素严格小于 toElement  
        SortedSet<E> tailSet(E fromElement);//返回此 set的部分视图,其元素大于等于 fromElement  
        E first();//set中第一个元素  
        E last();//set中最后一个元素  
    }

    NavigableSet

    public interface NavigableSet<E> extends SortedSet<E> {//扩展的 SortedSet,具有了搜索匹配元素方法          JDK1.7   java.util  
        E lower(E e);//返回此 set中小于给定元素的最大元素  
        E floor(E e);//返回此 set中小于等于给定元素的最大元素  
        E ceiling(E e);//返回此 set中大于等于给定元素的最小元素  
        E higher(E e);//返回此 set中大于给定元素的最小元素  
        E pollFirst();//获取并移除第一个元素  
        E pollLast();//获取并移除最后一个元素  
        Iterator<E> iterator();//以升序返回在此set的元素上进行迭代的迭代器  
        NavigableSet<E> descendingSet();//返回此 set中所包含元素的逆序视图  
        Iterator<E> descendingIterator();//以降序返回在此 set的元素上进行迭代的迭代器。效果等同于 descendingSet().iterator()。   
        //返回此 set 的部分视图,其元素范围从 fromElement 到 toElement  
        NavigableSet<E> subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive);
        //返回此 set的部分视图,其元素小于(或等于,如果 inclusive 为 true)toElement  
        NavigableSet<E> headSet(E toElement, boolean inclusive);
        //返回此 set的部分视图,其元素大于(或等于,如果 inclusive 为 true)fromElement  
        NavigableSet<E> tailSet(E fromElement, boolean inclusive);
        //返回此 set 的部分视图,其元素从 fromElement(包括)到 toElement(不包括)。  
        SortedSet<E> subSet(E fromElement, E toElement);
        //返回此 set的部分视图,其元素严格小于 toElement  
        SortedSet<E> headSet(E toElement);
        //返回此 set的部分视图,其元素大于等于 fromElement  
        SortedSet<E> tailSet(E fromElement);
    }

    HashSet

    public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable

    阅读HashSet的源码,其实很简单,就是在里面维护了一个 HashMap类型的成员变量,然后抽象出了几个增删改查的方法。需要深入了解的话可以阅读:java容器类2:Map及HashMap深入解读

    这里有个疑问,HashMap是存放键值对的,而HashSet是存放一组数据的,为什么可以用HashMap保存set数据?

    HashMap中的keySet()函数返回的就是一个 Set类型的数据(不能有重复的key值),所以HashSet将Set数组全部存放在HashMap的keySet中,value值全部用默认的一个Object类型的常量表示。

    HashSet中的add()函数可以看出

    public boolean add(E e) {
            return map.put(e, PRESENT)==null;
        }

    TreeSet


    TreeSet的继承关系如下,看上去还挺复杂

    1088209-20170227105335251-1963872270

    正如TreeSet继承自SortSet一样,TreeSet中存储了排序的数组(每个元素值不能有重复的元素)。

    同HashSet实现方法相同,里面维护了一个map(NavigableMap类型)类型的成员变量,来保证所有数据是有序的。map里面的keySet字段可以保存TreeSet的所有值。

    TreeSet中的方法都是基于NavigableMap的增删改查操作,这里不详细分析。

    参考:

    http://www.cnblogs.com/NeilZhang/p/8577991.html

  • 相关阅读:
    [CocosCreator]-12-音频播放
    [CocosCreator]-11-文本输入-EditBox 组件
    [CocosCreator]-10-Button(按钮)
    深入理解正则表达式高级教程
    正则表达式匹配次数
    如何理解正则表达式匹配过程
    正则表达式工具RegexBuddy使用教程
    正则表达式批量替换通过$
    正则前面的 (?i) (?s) (?m) (?is) (?im)
    Net操作Excel_NPOI
  • 原文地址:https://www.cnblogs.com/NeilZhang/p/8594361.html
Copyright © 2011-2022 走看看