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接口的总的集成关系如下图:


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的继承关系如下,看上去还挺复杂

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

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

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

参考:

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

原文地址:https://www.cnblogs.com/NeilZhang/p/8594361.html

时间: 2024-11-15 06:15:32

java容器类3:set/HastSet/MapSet深入解读的相关文章

java容器类4:Queue深入解读

Collection的其它两大分支:List和Set在前面已近分析过,这篇来分析一下Queue的底层实现. 前三篇关于Java容器类的文章: java容器类1:Collection,List,ArrayList,LinkedList深入解读 java容器类2:Map及HashMap深入解读 java容器类3:set/HastSet/MapSet深入解读 Queue public interface Queue<E> extends Collection<E> { boolean a

java容器类总结

java容器类只有两个主要类型:Collection和Map. Collection容器每个槽只有一个元素. Map中持有键值对关联. Collection子接口有List和Set. List:以特定次序存储元素.之类有ArrayList和LinkedList ArrayList:擅长随机访问. LinkedList:擅长插入.删除和移动元素. Vector:同步,安全,性能较低.其余基本和ArrayList一样. Set:不含重复元素. HashSet:使用散列函数. TreeSet:使用红黑

【转】java 容器类使用 Collection,Map,HashMap,hashTable,TreeMap,List,Vector,ArrayList的区别

原文网址:http://www.360doc.com/content/15/0427/22/1709014_466468021.shtml java 容器类使用 Collection,Map,HashMap,hashTable,TreeMap,List,Vector,ArrayList的区别. 经常会看到程序中使用了记录集,常用的有Collection.HashMap.HashSet.ArrayList,因为分不清楚它们之间的关系,所以在使用时经常会混淆,以至于不知道从何下手.在这儿作了一个小例

Java容器类基础

Java容器类基础 Java实用类库提供了一套相当完善的容器类,基本类型为List,Set,Map,Queue.它们都有一些特性,例如Set对于每一个值都只保存一个对象,Map允许你将对象和对象关联起来.此外,Java容器类都可以自动调节尺寸.因此,与数组不同,你可以放置任意数量的对象到容器中而不用担心容器应该设置为多大. Java容器类有4个接口,它们分别上面提到过的List,Set,Map,Queue:在理想情况下,你编写的代码大多数情况是在和这些接口打交道,并且你唯一需要指定所要使用精确类

Java容器类概述

1.简介 容器是一种在一个单元里处理一组复杂元素的对象.使用集合框架理论上能够减少编程工作量,提高程序的速度和质量,毕竟类库帮我们实现的集合在一定程度上时最优的.在Java中通过java.util为用户实现了一个Collection Framework,这个集合框架用统一的架构来表示和操作所有的集合,具体包含以下内容: interface:表示集合的抽象数据类型,它将容器的具体实现与提供的接口分离: implement:表示集合接口的具体实现: algorithms:对集合中的元素提供的一些泛型

Java容器类的深入理解

Java容器类包含List.ArrayList.Vector及map.HashTable.HashMap ArrayList和HashMap是异步的,Vector和HashTable是同步的,所以Vector和HashTable是线程安全的,而ArrayList和HashMap并不是线程安全的.因为同步需要花费机器时间,所以Vector和HashTable的执行效率要低于ArrayList和HashMap. Collection ├List       接口 │├LinkedList      

Java容器类接口的选择

我们知道Java容器类实际提供了四类接口:Map,List,Set和Queue,如下图所示,每种接口都有不止一个版本的实现,如果在实际编写程序时需要使用某种接口时该如何选择. 从Oracle的Java Language Best Practices 中的说明可以看到建议不要在新程序中使用HashTable,Vector,Stack使用HashMap,ArrayList和LinkedList来替换. ArrayList和LinkedList都实现了List接口,当ArrayList底层由数组实现,

java容器类的继承结构

摘要: java容器类的继承结构 Java容器类库定义了两个不同概念的容器,Collection和Map Collection 一个独立元素的序列,这些元素都服从一条或多条规则.List必须按照插入的顺序保存元素.Set不能有重复元素.Queue按照排队规则来确定对象产生的顺序. (文中Jdk源码版本无特殊说明均为jdk1.8.0_101) public interface Collection<E> extends Iterable<E> { 可以看到,java定义了Collec

Java容器类类库基本概念详解

  Java容器类类库的用途是"保存对象",并将其划分为两个不同的概念: Collection.一个独立元素的序列,这些元素都服从一条或多条规则.List必须按照插入的顺序保存元素,而Set不能有重复元素.Queue按照排队规则来确定对象产生的顺序(通常与它们被插入的顺序相同). Map.一组成对的"键值对"对象,允许你使用键来查找值.ArrayList允许你使用数字来查找值,因此在某种意义上讲,他将数字与对象关联在了一起.映射表允许我们使用另一个对象来查找某个对象