1.Set接口:
特点:
--无序【添加和取出的顺序不一致】,没有索引
--不允许重复元素,所以最多包含一个null
--和 List 接口一样, Set 接口也是 Collection 的子接口,因此,常用方法和 Collection 接口一样。
–HashSet
特点:
--HashSet 基于 HashMap 来实现的,是一个不允许有重复元素的集合。
--HashSet 允许有 null 值。
--HashSet 是无序的,即不会记录插入的顺序。
--HashSet 不是线程安全的, 如果多个线程尝试同时修改 HashSet,则最终结果是不确定的。 您必须在多线程访问时显式同步对 HashSet 的并发访问。
--HashSet 实现了 Set 接口。
--HashSet 中的元素实际上是对象,一些常见的基本类型可以使用它的包装类。
常见方法:
–TreeSet:
特点:
--TreeSet 是二叉树实现的,Treeset中的数据是自动排好序的,不允许放入null值。
--HashSet 是哈希表实现的,HashSet中的数据是无序的,可以放入null,但只能放入一个null,两者中的值都不能重复,就如数据库中唯一约束。
--HashSet要求放入的对象必须实现HashCode()方法,放入的对象,是以hashcode码作为标识的,而具有相同内容的 String对象,hashcode是一样,所以放入的内容不能重复。但是同一个类的对象可以放入不同的实例 。
TreeSet常见方法:
add(E e) // 如果不存在,则添加。
clear() //清空
contains(Object o)//查询指定元素是否存在,存在返回true
isEmpty() // 判空
iterator() //返回此容器的迭代器
remove // 如果指定元素在此set中则移除
size() //返回元素数量
2.Map接口:
特点:
--Map与Collection并列存在。用于保存具有映射关系的数据:key-value
--Map 中的key 和value 都可以是任何引用类型的数据
--Map 中的key 用Set来存放,不允许重复,即同一个Map 对象所对应的类,须重写hashCode()和equals()方法
--常用String类作为Map的“键”
--key 和value 之间存在单向一对一关系,即通过指定的key 总能找到唯一的、确定的value
--Map接口的常用实现类:HashMap、TreeMap、LinkedHashMap和Properties。
--HashMap 是Map 接口使用频率最高的实现类
–哈希表:
哈希表(HashTable,散列表)是根据key-value进行访问的数据结构,他是通过把key映射到表中的一个位置来访问记录,加快查找的速度,其中映射的函数叫做散列函数,存放记录的数组叫做散列表,哈希表的主干是数组
–HashMap:
--它是一个标准的哈希表
--JDK8之前,HashMap:整体结构是一个"数组 + 链表" 结构
--JDK8之后,HashMap:整体结构是一个"数组 + 链表 + 红黑树" 结构
–HashMap的构造方法
//1.指定容量和负载因子
public HashMap(int initialCapacity, float loadFactor) {
//判断初始容量是否合法
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal initial capacity: " +
initialCapacity);
//判断初始容量是否大于最大容量,如果大于则初始化为最大容量 1 << 30
if (initialCapacity > MAXIMUM_CAPACITY)
initialCapacity = MAXIMUM_CAPACITY;
//判断装载因子是否合法
//isNan()方法判断是否为数字
if (loadFactor <= 0 || Float.isNaN(loadFactor))
throw new IllegalArgumentException("Illegal load factor: " +
loadFactor);
this.loadFactor = loadFactor;
//计算扩容门槛
this.threshold = tableSizeFor(inistialCapacity);
}
//2.仅指定容量,使用默认的负载因子,内部实现实际上还是依赖的第一种方法
public HashMap(int initialCapacity) {
this(initialCapacity, DEFAULT_LOAD_FACTOR);
}
//3.使用默认容量和负载因子
public HashMap() {
this.loadFactor = DEFAULT_LOAD_FACTOR;
threshold = (int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);
table = new Entry[DEFAULT_INITIAL_CAPACITY];
init();
}
//4.根据指定的map初始化,根据指定的map的容量和默认容量共同决定初始化容量,使用默认负载因子
public HashMap(Map<? extends K, ? extends V> m) {
this(Math.max((int) (m.size() / DEFAULT_LOAD_FACTOR) + 1,DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR);
putAllForCreate(m);
}
–HashMap的put( K key,V value)方法:
1、首先会将key进行hash运算,如果为null,则hash值为0,否则
返回key的hashcode()的值(注意:该值会进行高低位异或运算)
目的是key的高低位二进制数据都参与到运算中来,是的key的
hash值足够散列(不要让key都插入到一个节点中)
2、添加节点:
如果数组没有初始化同时长度为0
如果是第一次添加节点,则容量是16,负载因子是0.75,触发扩容的阈值:12。
3、插入时,求插入key的下标
获取hashcode值,求模元素
(hash % length <===> (length - 1) & hash )