低价网站,auto post wordpress,网站建设所需材料,谷歌seo是做什么的1.Java集合有哪些#xff1f;集合类型主要有3种#xff1a;set(集#xff09;、list(列表#xff09;和map(映射)Map接口和Collection接口是所有集合框架的父接口#xff1a;1. Collection接口的子接口包括#xff1a;Set接口和List接口2. Map接口的实现类主要有#xf…1.Java集合有哪些集合类型主要有3种set(集、list(列表和map(映射)Map接口和Collection接口是所有集合框架的父接口1. Collection接口的子接口包括Set接口和List接口2. Map接口的实现类主要有HashMap、TreeMap、Hashtable、ConcurrentHashMap以及Properties等3. Set接口的实现类主要有HashSet、TreeSet、LinkedHashSet等4. List接口的实现类主要有ArrayList、LinkedList、Stack以及Vector等2.Java集合的快速失败机制 “fail-fast”是java集合的一种错误检测机制当多个线程对集合进行结构上的改变的操作时有可能会产生fail-fast 机制。例如假设存在两个线程线程1、线程2线程1通过Iterator在遍历集合A中的元素在某个时候线程2修改了集合A的结构是结构上面的修改而不是简单的修改集合元素的内容那么这个时候程序就会抛出 ConcurrentModificationException 异常从而产生fail-fast机制。原因迭代器在遍历时直接访问集合中的内容并且在遍历过程中使用一个 modCount 变量。集合在被遍历期间如果内容发生变化就会改变modCount的值。每当迭代器使用hashNext()/next()遍历下一个元素之前都会检测modCount变量是否为expectedmodCount值是的话就返回遍历否则抛出异常终止遍历。解决办法1. 在遍历过程中所有涉及到改变modCount值得地方全部加上synchronized。2. 使用CopyOnWriteArrayList来替换ArrayList简单的说就是一个线程正在遍历集合此时另一个线程删了一个元素就会抛异常处理方式也很容易加锁也就是使用synchronized关键字此关键字后面将线程安全讲还有就是用CopyOnWriteArrayList它在“添加/修改/删除”数据时,都会新建一个数组,并将更新后的数据拷贝到新建的数组中,最后再将该数组赋值给“volatile数组”。3.怎么确保一个集合不能被修改可以使用 Collections. unmodifiableCollection(Collection c) 方法来创建一个只读集合这样改变集合的任何操作都会抛出 Java. lang. UnsupportedOperationException 异常。4.List接口4.1迭代器 Iterator 是什么Iterator 接口提供遍历任何 Collection 的接口。我们可以从一个 Collection 中使用迭代器方法来获取迭代器实例。可以实现一边遍历一边删除这是for循环遍历所不能实现的。IteratorInteger it list.iterator();
while(it.hasNext()){
*// do something*it.remove();
}Iterator是一个可以实现在遍历的时候删除而不报错的接口4.2遍历一个 List 有哪些不同的方式每种方法的实现原理是什么1. for 循环遍历基于计数器。在集合外部维护一个计数器然后依次读取每一个位置的元素当读取到最后一个元素后停止。2. 迭代器遍历Iterator。Iterator 是面向对象的一个设计模式目的是屏蔽不同数据集合的特点统一遍历集合的接口。Java 在 Collections 中支持了 Iterator 模式。3. foreach 循环遍历。foreach 内部也是采用了 Iterator 的方式实现使用时不需要显式声明Iterator 或计数器。优点是代码简洁不易出错缺点是只能做简单的遍历不能在遍历过程中操作数据集合例如删除、替换。4.3 Java 中 List遍历的最佳实践是什么最佳实践Java Collections 框架中提供了一个 RandomAccess 接口用来标记 List 实现是否支持 Random Access。如果一个数据集合实现了该接口就意味着它支持 Random Access按位置读取元素的平均时间复杂度为 O(1)如ArrayList。如果没有实现该接口表示不支持 Random Access如LinkedList。推荐的做法就是支持 Random Access 的列表可用 for 循环遍历否则建议用 Iterator 或foreach 遍历。4.4说一下 ArrayList 的优缺点ArrayList的优点如下ArrayList 底层以数组实现是一种随机访问模式。ArrayList 实现了 RandomAccess 接口因此查找的时候非常快。ArrayList 在顺序添加一个元素的时候非常方便。ArrayList 的缺点如下删除元素的时候需要做一次元素复制操作。如果要复制的元素很多那么就会比较耗费性能。插入元素的时候也需要做一次元素复制操作缺点同上。头插头删比较消耗性能ArrayList 比较适合顺序添加、随机访问的场景。4.5 ArrayList是线程安全的吗当然不是线程安全版本的数组容器是Vector。Vector的实现很简单就是把所有的方法统统加上synchronized就完事了。你也可以不使用Vector用Collections.synchronizedList把一个普通ArrayList包装成一个线程安全版本的数组容器也可以原理同Vector是一样的就是给所有的方法套上一层synchronized。不存在一个集合工具是查询效率又高增删效率也高的还线程安全的因为数据结构的特性就是优劣共存的想找个平衡点很难牺牲了性能那就安全牺牲了安全那就快速。4.6 数组的长度是有限制的而ArrayList是可以存放任意数量对象那么他是怎么实现的呢其实实现方式比较简单他就是通过数组扩容的方式去实现的。就比如我们现在有一个长度为10的数组现在我们要新增一个元素发现已经满了那ArrayList会怎么做呢10是默认长度第一步他会重新定义一个长度为1010/2的数组也就是新增一个长度为15的数组。每次扩容都是原来长度的1.5倍然后把原数组的数据原封不动的复制到新数组中这个时候再把指向原数的地址换到新数组ArrayList就这样完成了一次改头换面。4.7 能说一下ArrayList在增删的时候是怎么做的么主要说一下他为啥慢。他有指定index新增也有直接新增的在这之前他会有一步校验长度的判断ensureCapacityInternal就是说如果长度不够是需要扩容的。在扩容的时候老版本的jdk和8以后的版本是有区别的8之后的效率更高了采用了位运算右移一位其实就是除以2这个操作。指定位置新增的时候在校验之后的操作很简单就是数组的copy大家可以看下代码。画个图解释下你可能就明白一点比如有下面这样一个数组我需要在index 5的位置去新增一个元素A那从代码里面我们可以看到他复制了一个数组是从index 5的位置开始的然后把它放在了index 51的位置给我们要新增的元素腾出了位置然后在index的位置放入元素A就完成了新增的操作了至于为啥说他效率低我想我不说你也应该知道了我这只是在一个这么小的List里面操作要是我去一个几百几千几万大小的List新增一个元素那就需要后面所有的元素都复制然后如果再涉及到扩容啥的就更慢了不是嘛。4.8 LinkList链表LinkedList 是用链表结构存储数据的很适合数据的动态插入和删除随机访问和遍历速度比较慢。另外他还提供了 List 接口中没有定义的方法专门用于操作表头和表尾元素可以当作堆栈、队列和双向队列使用。4.9 ArrayList 和 LinkedList 的区别是什么数据结构实现ArrayList 是动态数组的数据结构实现而 LinkedList 是双向链表的数据结构实现。随机访问效率ArrayList 比 LinkedList 在随机访问的时候效率要高因为 LinkedList 是线性的数据存储方式所以需要移动指针从前往后依次查找。增加和删除效率在非首尾的增加和删除操作LinkedList 要比 ArrayList 效率要高因为ArrayList 增删操作要影响数组内的其他数据的下标。内存空间占用LinkedList 比 ArrayList 更占内存因为 LinkedList 的节点除了存储数据还存储了两个引用一个指向前一个元素一个指向后一个元素。线程安全ArrayList 和 LinkedList 都是不同步的也就是不保证线程安全综合来说在需要频繁读取集合中的元素时更推荐使用 ArrayList而在插入和删除操作较多时更推荐使用 LinkedList。LinkedList 的双向链表也叫双链表是链表的一种它的每个数据结点中都有两个指针分别指向直接后继和直接前驱。所以从双向链表中的任意一个结点开始都可以很方便地访问它的前驱结点和后继结点。总结ArrayList是实现了基于动态数组的数据结构而LinkedList是基于链表的数据结构 对于随机访问get和setArrayList要优于LinkedList因为LinkedList要移动指针对于添加和删除操作add和remove两种数据结构谁快谁慢取决于数据量的大小通常采用ArrayList能满足大部分的使用场景除非需要使用LinkedList实现队列、栈等数据结构。若使用头插法插入数据使用linkedList效率大于arrayList使用尾插法数据量过大时arrayList效率高于LinkedList若根据下标查找数据arrayList效率高若根据值来查找数据arrayList和LinkedList效率差不多。4.10 ArrayList 和 Vector 的区别是什么这两个类都实现了 List 接口List 接口继承了 Collection 接口他们都是有序集合线程安全Vector 使用了 Synchronized 来实现线程同步是线程安全的而 ArrayList 是非线程安全的。性能ArrayList 在性能方面要优于 Vector。扩容ArrayList 和 Vector 都会根据实际的需要动态的调整容量只不过在 Vector 扩容每次会增加 1 倍而 ArrayList 只会增加 50%。Vector类的所有方法都是同步的。可以由两个线程安全地访问一个Vector对象、但是一个线程访问Vector的话代码要在同步操作上耗费大量的时间。Arraylist不是同步的所以在不需要保证线程安全时时建议使用Arraylist。4.11 为什么 ArrayList 的 elementData 加上 transient 修饰什么是序列化Java中对象的序列化指的是将对象转换成以字节序列的形式来表示这些字节序列包含了对象的数据和信息一个序列化后的对象可以被写到数据库或文件中也可用于网络传输。transient关键字的作用对于transient 修饰的成员变量在类的实例对象的序列化处理过程中会被忽略。 因此transient变量不会贯穿对象的序列化和反序列化生命周期仅存于调用者的内存中而不会写到磁盘里进行持久化。可以看到 ArrayList 实现了 Serializable 接口这意味着 ArrayList 支持序列化。transient 的作用是说不希望 elementData 数组被序列化重写了 writeObject 实现 /*** Save the state of the ttArrayList/tt instance to a stream (that* is, serialize it).** serialData The length of the array backing the ttArrayList/tt* instance is emitted (int), followed by all of its elements* (each an ttObject/tt) in the proper order.*/private void writeObject(java.io.ObjectOutputStream s)throws java.io.IOException{// Write out element count, and any hidden stuffint expectedModCount modCount;s.defaultWriteObject();// Write out size as capacity for behavioural compatibility with clone()s.writeInt(size);// Write out all elements in the proper order.for (int i0; isize; i) {s.writeObject(elementData[i]);}if (modCount ! expectedModCount) {throw new ConcurrentModificationException();}}每次序列化时先调用 defaultWriteObject() 方法序列化 ArrayList 中的非 transient 元素然后遍历 elementData只序列化已存入的元素这样既加快了序列化的速度又减小了序列化之后的文件大小。5. Set5.1 List 和 Set 的区别List , Set 都是继承自Collection 接口List 特点一个有序元素存入集合的顺序和取出的顺序一致容器元素可以重复可以插入多个null元素元素都有索引。常用的实现类有 ArrayList、LinkedList 和 Vector。Set 特点一个无序存入和取出顺序有可能不一致容器不可以存储重复元素只允许存入一个null元素必须保证元素唯一性。Set 接口常用实现类是 HashSet、LinkedHashSet 以及TreeSet。另外 List 支持for循环也就是通过下标来遍历也可以用迭代器但是set只能用迭代因为他无序无法用下标来取得想要的值。Set和List对比Set检索元素效率低下删除和插入效率高插入和删除不会引起元素位置改变。List和数组类似List可以动态增长查找元素效率高插入删除元素效率低因为会引起其他元素位置改变5.2 说一下 HashSet 的实现原理HashSet 是基于 HashMap 实现的HashSet的值存放于HashMap的key上HashMap的value统一为present因此 HashSet 的实现比较简单相关 HashSet 的操作基本上都是直接调用底层HashMap 的相关方法来完成HashSet 不允许重复的值。这里可能会有疑惑HashMap是keyvalue形式而HashSet是单值形式为什么能复用HashMap的方法呢看代码HashSet的add()方法这个PRESENT 又是个啥上面注释这句话啥意思呢就是说赋了一个假值即Map的value都是这个PRESENT 假的值 因为不需要知道value只要求key不重复。