先看再点赞,给自己一点思考的时间,如果对自己有帮助,微信搜索【程序职场】关注这个执着的职场程序员。
价值:Java技能,面试经验指导,简历优化,职场规划指导,技能提升方法,讲不完的职场故事,个人成长经验
这几天研究了一下华为鸿蒙系统app开发,研究中发现只能做一些基础的开发,如果想要做一个完整的项目估计还需要不断完善基础组件和底层架构。
感兴趣的小伙伴可以关注我,我计划三篇文章讲完鸿蒙系统app开发,并且你看完也能学会鸿蒙app开发,目前已经更新一篇。
今天这篇文章主要说 面试 字节时候的一道面试题,这个面试题我们在项目开发中其实很普遍,是一个我们常用的数据存储方式,也是我们必须要了解的。
01
概念
Vector类
Vector非常类似ArrayList,但是Vector是同步的。由Vector创建的Iterator,虽然和ArrayList创建的Iterator是同一接口,但是,因为Vector是同步的,当一个Iterator被创建而且正在被使用,另一个线程改变了Vector的状态(例如,添加或删除了一些元素),这时调用Iterator的方法时将抛出ConcurrentModificationException,因此必须捕获该异常。
ArrayList类
ArrayList实现了可变大小的数组。它允许所有元素,包括null。ArrayList没有同步。
size,isEmpty,get,set方法运行时间为常数。但是add方法开销为分摊的常数,添加n个元素需要O(n)的时间。其他的方法运行时间为线性。
每个ArrayList实例都有一个容量(Capacity),即用于存储元素的数组的大小。这个容量可随着不断添加新元素而自动增加,但是增长算法并没有定义。当需要插入大量元素时,在插入前可以调用ensureCapacity方法来增加ArrayList的容量以提高插入效率。
LinkedList类
LinkedList实现了List接口,允许null元素。此外LinkedList提供额外的get,remove,insert方法在LinkedList的首部或尾部。这些操作使LinkedList可被用作堆栈(stack),队列(queue)或双向队列(deque)。
02
区别
1、Vector、ArrayList都是以类似数组的形式存储在内存中,LinkedList则以链表的形式进行存储。
2、List中的元素有序、允许有重复的元素,Set中的元素无序、不允许有重复元素。
3、Vector线程同步,ArrayList、LinkedList线程不同步。
4、LinkedList适合指定位置插入、删除操作,不适合查找;ArrayList、Vector适合查找,不适合指定位置的插入、删除操作。
5、ArrayList在元素填满容器时会自动扩充容器大小的50%,而Vector则是100%,因此ArrayList更节省空间。
6、ArrayList、Vector、LinkedList类都是java.util包中,均为可伸缩数组。
7、ArrayList和Vector底层都是数组实现的,所以,索引数据快,删除、插入数据慢。
8、Vector线程安全,ArrayList、LinkedList非线程安全。
Vector:缺省的情况下,增长为原数组长度的一倍。说到缺省,说明他其实是可以自主设置初始化大小的。
ArrayList:自动增长原数组的50%。
03
安全性
Vector是同步的。这个类中的一些方法保证了Vector中的对象是线程安全的。
而ArrayList则是异步的,因此ArrayList中的对象并不是线程安全的。
Vector由于使用了synchronized方法(线程安全)。
和ArrayList一样,LinkedList也是非同步的(unsynchronized)
总结如下:
Vector:线程安全
ArrayList:非线程安全
LinkedList:非线程安全
04
继承关系
ArrayList,LinkedList和Vector都继承自List接口。ArrayList和Vector的底层是动态数组,LinkedList的底层是双向链表.
也就是说都实现了get(int location)、remove(int location)等“根据索引值来获取、删除节点的函数”。
数组结构根据下标取值很容易,LinkedList双向列表的实现也比较简单,通过计数索引值实现,从链表长度的1/2开始查找,下标大了就从表头开始找,小了就从表尾开始找。
05
存储数据结构
ArrayList:数组
Vector:数组
LinkedList:双向链表
数组:可以根据下标快速查找,所以大部分情况下,查询快。
链表:增加和删除元素方便,增加或删除一个元素,仅需处理结点间的引用即可。
06
实例应用
1,LinkedList
public boolean add(E e) {
linkLast(e);
return true;
}
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
分析:我们可以看到每新增一个元素就要创建一个Node对象,进行频繁的赋值操作 “final Node<E> newNode = new Node<>(l, e, null);”对效率有一定的影响。
2,ArrayList
public void add(int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1);//Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
分析:从代码中我们可以看出,每插入一个元素就要进行大量元素复制操作:“System.arraycopy(elementData, index, elementData, index + 1,size - index);”
3,Vector 实例
import java.util.Vector;
import java.util.List;
import java.util.Iterator;
import java.util.Enumeration;
/**
* @desc Vector测试函数:遍历Vector和常用API
*
* @author skywang
*/
public class VectorTest {
public static void main(String[] args) {
// 新建Vector
Vector vec = new Vector();
// 添加元素
vec.add("1");
vec.add("2");
vec.add("3");
vec.add("4");
vec.add("5");
// 设置第一个元素为100
vec.set(0, "100");
// 将“500”插入到第3个位置
vec.add(2, "300");
System.out.println("vec:"+vec);
// (顺序查找)获取100的索引
System.out.println("vec.indexOf(100):"+vec.indexOf("100"));
// (倒序查找)获取100的索引
System.out.println("vec.lastIndexOf(100):"+vec.lastIndexOf("100"));
// 获取第一个元素
System.out.println("vec.firstElement():"+vec.firstElement());
// 获取第3个元素
System.out.println("vec.elementAt(2):"+vec.elementAt(2));
// 获取最后一个元素
System.out.println("vec.lastElement():"+vec.lastElement());
// 获取Vector的大小
System.out.println("size:"+vec.size());
// 获取Vector的总的容量
System.out.println("capacity:"+vec.capacity());
// 获取vector的“第2”到“第4”个元素
System.out.println("vec 2 to 4:"+vec.subList(1, 4));
// 通过Enumeration遍历Vector
Enumeration enu = vec.elements();
while(enu.hasMoreElements())
System.out.println("nextElement():"+enu.nextElement());
Vector retainVec = new Vector();
retainVec.add("100");
retainVec.add("300");
// 获取“vec”中包含在“retainVec中的元素”的集合
System.out.println("vec.retain():"+vec.retainAll(retainVec));
System.out.println("vec:"+vec);
// 获取vec对应的String数组
String[] arr = (String[]) vec.toArray(new String[0]);
for (String str:arr)
System.out.println("str:"+str);
// 清空Vector。clear()和removeAllElements()一样!
vec.clear();
// vec.removeAllElements();
// 判断Vector是否为空
System.out.println("vec.isEmpty():"+vec.isEmpty());
}
}
文末送书
文末送书时刻!送的书分别是:
Node.js企业级应用开发实战(北京大学出版社提供 3本)
Redis设计与实现 (机械工业出版社提供 1本)
在此感谢北京大学出版社,机械工业出版社的支持。
送书规矩
从留言区中选中奖者,按照留言者的点赞,分享数选择,点赞,分享数高者获得书一本,累计送书 四本。时间截止9月18日的20点。
送的书籍
Node.js企业级应用开发实战
Redis设计与实现