同步操作将从 Java精选/Ebooks 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
可以使用Collections包下的unmodifiableMap()方法,通过这个方法返回的map是不可以修改的。这样改变集合的任何操作都会抛出Java.lang.UnsupportedOperationException异常。
Collections包也提供了对list和set集合的方法。
Collections.unmodifiableList(List)
Collections.unmodifiableSet(Set)
也可以使用Collections.unmodifiableCollection(Collection c)方法来创建一个只读集合,这样改变集合的任何操作都会抛出Java.lang.UnsupportedOperationException异常。
示例代码:
List<String> list = new ArrayList<>();
list. add("微信公众号");
Collection<String> unmlist = Collections.unmodifiableCollection(list);
unmlist.add("Java精选"); // 运行时此行报错
System.out.println(list.size());
HashMap一般采用String、Integer 等类作为key、因为这些类底层已经重写了hashcode、equals方法,用的是final修饰类在多线程情况下相对安全。
数组位置确定用的是与运算,仅仅最后四位有效,设计者将key的哈希值与高16为做异或运算使得在做&运算确定数组的插入位置时,此时的低位实际是高位与低位的结合,增加了随机性,减少了哈希碰撞的次数。
HashMap默认初始化长度为16,并且每次自动扩展或者是手动初始化容量时,必须是2的幂。
Java集合类是一种非常实用的工具类,主要用于保存、盛装其它数据(集合里只能保存对象),因此集合类也被成为容器类。
所有的集合类都位于java.util包下,在java.util.concurrent下还提供了一些支持多线程的集合类。
Java的集合类主要由两个接口派生而来:Collection和Map,这两个是Java集合框架的根接口。
Collection接口
Collection派生出三个子接口,Set代表不可重复的无序集合、List代表可重复的有序集合、Queue是java提供的队列实现;Collection是最基本的集合接口,它提供了一些通用的方法,供子接口调用。
Map接口
Map实现类都用于保存具有映射关系的数据,它们保存的数据都是key-value对,如果要查找Map中的数据,总是根据key来获取,所以key是不可重复的,它用于标识集合里的每项数据。
fail-fast(快速失败)是Java对java.util包下的所有集合类的是一种错误检测机制。
Java泛型是J2 SE1.5中引入的一个新特性,其本质是参数化类型,也就是说所操作的数据类型被指定为一个参数(type parameter),这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。
泛型意味着编写代码可以被不同类型的对象所重用,为了编写重用性更好的代码。泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。
比如常见集合类LinkedList源码如下:
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{
transient int size = 0;
/**
* Pointer to first node.
* Invariant: (first == null && last == null) ||
* (first.prev == null && first.item != null)
*/
transient Node<E> first;
...
}
1、Collection接口存储一组不唯一,无序的对象;
2、List接口存储一组不唯一,有序(插入顺序)的对象;
3、Set接口存储一组唯一,无序的对象;
4、Map接口存储一组键值对象,提供key到value的映射。Key无序且唯一。value不要求有序,允许重复。(如果只使用key存储,而不使用value,那就是Set)。
HashSet实现了Set接口,它不允许集合中有重复的值,当我们提到HashSet时,第一件事情就是在将对象存储在HashSet之前,要先确保对象重写equals()和hashCode()方法,这样才能比较对象的值是否相等,以确保set中没有储存相等的对象。如果我们没有重写这两个方法,将会使用这个方法的默认实现。
public boolean add(Object o);
该方法用来在Set中添加元素,当元素值重复时则会立即返回false,如果成功添加的话会返回true。
1)哈希表的查询速度特别快,时间复杂度为O(1)。
2)HashMap、Hashtable、HashSet这些集合采用的是哈希表结构,需要用到hashCode哈希码,hashCode是一个整数值。
3)系统类已经覆盖了hashCode方法,自定义类如果要放入hash类集合,必须重写hashcode。如果不重写,调用的是Object的hashcode,而Object的hashCode实际上是地址。
4)向哈希表中添加数据的原理:当向集合Set中增加对象时,首先集合计算要增加对象的hashCode码,根据该值来得到一个位置用来存放当前对象,如在该位置没有一个对象存在的话,那么集合Set认为该对象在集合中不存在,直接增加进去。如果在该位置有一个对象存在的话,接着将准备增加到集合中的对象与该位置上的对象进行equals方法比较,如果该equals方法返回false,那么集合认为集合中不存在该对象,在进行一次散列,将该对象放到散列后计算出的新地址里。如果equals方法返回true,那么集合认为集合中已经存在该对象了,不会再将该对象增加到集合中了。
5)在哈希表中判断两个元素是否重复要使用到hashCode()和equals()。hashCode决定数据在表中的存储位置,而equals判断是否存在相同数据。
6)Y=K(X) :K是函数,X是哈希码,Y是地址。
1、计算关于key的hashcode值(与Key.hashCode的高16位做异或运算)
2、如果散列表为空时,调用resize()初始化散列表
3、如果没有发生碰撞,直接添加元素到散列表中去
4、如果发生了碰撞(hashCode值相同),进行三种判断
1)若key地址相同或者equals后内容相同,则替换旧值
2)如果是红黑树结构,就调用树的插入方法
3)链表结构,循环遍历直到链表中某个节点为空,尾插法进行插入,插入之后判断链表个数是否到达变成红黑树的阙值8;也可以遍历到有节点与插入元素的哈希值和内容相同,进行覆盖。
5、如果桶满了大于阀值,则resize进行扩容
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。