java SE 集合(四)
来源:互联网 发布:gif编辑文字软件 编辑:程序博客网 时间:2024/05/20 21:22
预备知识:在java中Object类中的hashcode();方法返回该对象的内存真实地址的整数化表示,这个形象的不是真实地址的整数值就是哈希码
Set接口是collection 的另一个子接口本节将分析Set接口,以下内容来自(API)
public interface Set<E>
- extends Collection<E>
一个不包含重复元素的 collection。更确切地讲,set 不包含满足 e1.equals(e2)
的元素对 e1
和e2
,并且最多包含一个 null 元素。正如其名称所暗示的,此接口模仿了数学上的set 抽象。
在所有构造方法以及 add、equals 和 hashCode 方法的协定上,Set 接口还加入了其他规定,这些规定超出了从Collection 接口所继承的内容。出于方便考虑,它还包括了其他继承方法的声明(这些声明的规范已经专门针对Set 接口进行了修改,但是没有包含任何其他的规定)。
Set的实现类HashSet:HashSet 类按照哈希算法来存取集合中的对象,具有很好的存取和查找性能,当向集合中加入一个对象时,HashSet会调用hashcode()方法来获得哈希码,然后根据这个哈希码进一步计算出对象在集合中的存放位置;哈希表里可以存储元素的位置称作“桶”,通常情况下,单个桶里只存放一个元素,此时哈希表有最好的性能,哈希算法可以根据哈希码算出桶的存储位置,接着从桶中取出元素,但是当发生哈希冲突时,一个桶中存放大于一个的元素,这些元素一链表存储,必须按顺序搜索。
由一个类创建的对象哈希码是不同的,所以哪怕对象的内容一样,也有不一样的哈希码,就会被放在不同的桶中,那么就违反了Hashset中不允许重复元素的约定,此刻有必要重写她的hashcode()方法,使其哈希码一样那么就会在同一个桶中通过重写equals方法使其返回true那么相同的元素就无法放进HashSet集合
对于 HashSet 而言,它是基于 HashMap 实现的,HashSet 底层采用 HashMap 来保存所有元素,因此 HashSet 的实现比较简单,查看 HashSet 的源代码,可以看到如下代码:
- public class HashSet<E>
- extends AbstractSet<E>
- implements Set<E>, Cloneable, java.io.Serializable
- {
- // 使用 HashMap 的 key 保存 HashSet 中所有元素
- private transient HashMap<E,Object> map;
- // 定义一个虚拟的 Object 对象作为 HashMap 的 value
- private static final Object PRESENT = new Object();
- ...
- // 初始化 HashSet,底层会初始化一个 HashMap
- public HashSet()
- {
- map = new HashMap<E,Object>();
- }
- // 以指定的 initialCapacity、loadFactor 创建 HashSet
- // 其实就是以相应的参数创建 HashMap
- public HashSet(int initialCapacity, float loadFactor)
- {
- map = new HashMap<E,Object>(initialCapacity, loadFactor);
- }
- public HashSet(int initialCapacity)
- {
- map = new HashMap<E,Object>(initialCapacity);
- }
- HashSet(int initialCapacity, float loadFactor, boolean dummy)
- {
- map = new LinkedHashMap<E,Object>(initialCapacity
- , loadFactor);
- }
- // 调用 map 的 keySet 来返回所有的 key
- public Iterator<E> iterator()
- {
- return map.keySet().iterator();
- }
- // 调用 HashMap 的 size() 方法返回 Entry 的数量,就得到该 Set 里元素的个数
- public int size()
- {
- return map.size();
- }
- // 调用 HashMap 的 isEmpty() 判断该 HashSet 是否为空,
- // 当 HashMap 为空时,对应的 HashSet 也为空
- public boolean isEmpty()
- {
- return map.isEmpty();
- }
- // 调用 HashMap 的 containsKey 判断是否包含指定 key
- //HashSet 的所有元素就是通过 HashMap 的 key 来保存的
- public boolean contains(Object o)
- {
- return map.containsKey(o);
- }
- // 将指定元素放入 HashSet 中,也就是将该元素作为 key 放入 HashMap
- public boolean add(E e)
- {
- return map.put(e, PRESENT) == null;
- }
- // 调用 HashMap 的 remove 方法删除指定 Entry,也就删除了 HashSet 中对应的元素
- public boolean remove(Object o)
- {
- return map.remove(o)==PRESENT;
- }
- // 调用 Map 的 clear 方法清空所有 Entry,也就清空了 HashSet 中所有元素
- public void clear()
- {
- map.clear();
- }
- ...
- }
- java SE 集合(四)
- java SE 集合(三)
- Java SE 基础:集合(1)
- Java SE 基础:集合(2)
- Java SE --- 集合
- java se 集合 笔记
- Java Se ----集合框架
- Java Se ----集合框架
- java se 集合类
- JAVA SE集合总结
- Java SE基础知识点总结(四)
- Java 集合(四)
- Java集合(四)
- Java SE 之 Collection集合
- Java SE学习笔记-集合
- JAVA SE——集合
- Java SE之集合学习
- JAVA SE回顾---集合(1)
- 第二周作业
- wmap搭建————自己记录以备以后使用
- Sina微博应用开发指南
- ZOJ-2730
- 微软面试100题
- java SE 集合(四)
- poj 2092 Grandpa is Famous
- 因for(;i--;)引起的for语句学习。
- 希尔排序
- 神秘的Java Boolean的哈希值
- Windows和Ubuntu双系统完全独立的安装方法
- poj 1852
- EAGAIN、EWOULDBLOCK、EINTR与非阻塞 长连接
- 用C语言检测文本编码的方法