arraylist相关知识
-
ArrayList和LinkedListArrayList的3种初始化方式 //无参构造方法,默认初始化长度0(java 8) public ArrayList(); //用一个Collection对象初始化长度,并将元素添加到ArrayList中 public ArrayList(Collection<? extends E> c); //指定长度 public ArrayList(int initialCapacity); 关于ArrayList扩容 下面是部分源码 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; private static final int DEFAULT_CAPACITY = 10; protected transient int modCount
-
ArrayList 源码分析1)ArrayList 特点List 接口的可变数组实现,ArrayList 允许使用任何元素,包括 null。ArrayList 和 Vector 基本类似,只不过 Vector 是线程安全的,ArrayList 是线程不安全的。size、isEmpty、get、set、iterator 和 listIterator 以常量时间运行,其他的操作基本以线性时间运行。每个 ArrayList 都有一个容量,容量表示该 ArrayList 当前能容纳的元素个数,随着元素的增加,ArrayList 会自动扩容。在创建 ArrayList 时可以指定一个合适的初始化容量,以减少频繁扩容带来的性能损耗。ArrayList 是线程不安全的,多线程并发访问 ArrayList 并且至少有一个线程修改了它的结构【增加、删除元素、扩容等】,则 ArrayList 将抛出 ConcurrentModificationException 异常。快速失败机制:iterator 和 listIterator 返回的迭代器是快速失败的
-
ArrayList和Vector、LinkedListVector是同步的,是线程安全的,ArrayList不是线程同步的,而且线程同步是影响性能的,所以性能上ArrayList优于Vector。当Vector或ArrayList中的元素超过它的初始大小时,Vector会将它的容量翻倍,而ArrayList只增加50%的大小,这样,ArrayList就有利于节约内存空间。ArrayList的内部实现是基于内部数组Object[],所以从概念上讲,它更象数组,但LinkedList的内部实现是基于一组连接的记录,所以,它更象一个链表结构,所以,它们在性能上有很大的差别:从上面的分析可知,在ArrayList的前面或中间插入数据时,你必须将其后的所有数据相应的后移,这样必然要花费较多时间,所以,当你的操作是在一列数据的后面添加数据而不是在前面或中间,并且需要随机地访问其中的元素时,使用ArrayList会提供比较好的性能;而访问链表中的某个元素时,就必须从链表的一端开始沿着连接方向一个一个元素地去查找,直到找到所需的元素为止,所以,当你的操作是在一列数据的前面或中
-
ArrayList扩容机制这是一道有赞的面试题,JDK源码中的内容,了解一下对自己也没坏处。ArrayList使用一般新建ArrayList //DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {} //相当于new ArrayList(0) public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } public ArrayList(int initia
arraylist相关课程
arraylist相关教程
- 3. ArrayList和LinkeList 经过前面的学习我们已经知道了 ArrayList 是基于数组的,查询快插入慢,LinkedList 是基于链表的,插入快遍历慢。我们来做个实验看一下是不是真的如此:Integer index = 10000000;List<Integer> arrayList = new ArrayList<Integer>();List<Integer> linkedList = new LinkedList<Integer>();Long arrayStart = new Date().getTime();for (int i = 0; i < index; i++){ arrayList.add(i);}Long arrayEnd = new Date().getTime();Long linkedStart = new Date().getTime();for (int j = 0; j < index; j++) { linkedList.add(j);}Long linkedEnd = new Date().getTime();System.out.println("插入"+index+"条记录:");System.out.println("ArrayList耗时:"+(arrayEnd-arrayStart)+"毫秒");System.out.println("LinkedList耗时:"+(linkedEnd-linkedStart)+"毫秒");结果:插入 10000000 条记录:ArrayList 耗时:359 毫秒LinkedList 耗时:2891 毫秒我们会发现两者相差并不大,而且当我们把数据量上升到 10000000 的时候还会发现 ArrayList 的效率反而更快,这是什么原因呢。原来我们使用的 add (E e) 方法有这样的注释:Appends the specified element to the end of this list (optional operation).所以当把元素追加在最后的时候,数组中的其他元素不需要移动,此时 ArrayList 的处理效率也很不错。那么我们换个思路再试://元素个数减少到10万即可看出效果Integer index = 100000;List<Integer> arrayList = new ArrayList<Integer>();List<Integer> linkedList = new LinkedList<Integer>();Long arrayStart = new Date().getTime();for (int i = 0; i < index; i++){ //其他代码不变,我们将每次遍历时添加新元素的位置固定为第一个 arrayList.add(0,i);}Long arrayEnd = new Date().getTime();Long linkedStart = new Date().getTime();for (int j = 0; j < index; j++) { //其他代码不变,我们将每次遍历时添加新元素的位置固定为第一个 linkedList.add(0,j);}Long linkedEnd = new Date().getTime();System.out.println("插入"+index+"条记录:");System.out.println("ArrayList耗时:"+(arrayEnd-arrayStart)+"毫秒");System.out.println("LinkedList耗时:"+(linkedEnd-linkedStart)+"毫秒");结果:插入 100000 条记录ArrayList 耗时:828 毫秒LinkedList 耗时:16 毫秒这个测试结果跟理论就匹配上了,ArrayList 把大量的时间都用在了移动元素上,而 LinkedList 不需要做这样的操作,所以此时它的效率优势体现的非常明显。所以我们在日常使用中一定要区分,在使用 add 方法的时候是否需要指定新添加元素的位置,另外,由于 ArrayList 是基于无序数组的,因此遍历的时候可能输出顺序和插入顺序是不一致的,而 LinkedList 由于有严格的指针相连,顺序一定是固定的。所以我们生成第二组结论:需要频繁在指定位置添加、删除元素,而查询指定位置数据较少的场景优先使用 LinkedList;随机查询较多、在指定位置添加、删除元素较少,或者干脆不关心插入或删除元素的位置及遍历顺序时,优先使用 ArrayList;需要元素按顺序排列时,使用 LinkedList;
- 3.2 ArrayList 实现类 ArrayList 可以理解为动态数组,它的容量可以动态增长。当添加元素时,如果发现容量已满,会自动扩容为原始大小的 1.5 倍。3.2.1 构造方法ArrayList():构造一个初始容量为 10 的空列表;ArrayList(int initialCapacity):构造一个指定容量的空列表;ArrayList(Collection<? extends E> c):构造一个包含指定集合元素的列表,其顺序由集合的迭代器返回。在代码中,我们可以这样实例化ArrayList对象:// 无参构造实例化,初始容量为10List arrayList1 = new ArrayList();// 实例化一个初始容量为20的空列表List arrayList2 = new ArrayList(20);// 实例化一个集合元素为 arrayList2 的列表(由于 arrayList2 为空列表,因此其实例化的对象也为空列表)List arrayList3 = new ArrayList(arrayList2);3.2.2 常用成员方法void add(E e):将指定的元素追加到此列表的末尾;void add(int index, E element):将指定的元素插入此列表中的指定位置;E remove(int index):删除此列表中指定位置的元素;boolean remove(Object o):如果存在指定元素,则从该列表中删除第一次出现的该元素;void clear():从此列表中删除所有元素;E set(int index, E element):用指定的元素替换此列表中指定位置的元素;E get(int index):返回此列表中指定位置的元素;boolean contains(Object o):如果此列表包含指定的元素,则返回 true,否则返回 false;int size():返回该列表中元素的数量;Object[] toArray():以正确的顺序(从第一个元素到最后一个元素)返回一个包含此列表中所有元素的数组。更多成员方法请翻阅官方文档,下面我们将结合实例来介绍以上成员方法的使用。
- 2. Vector和ArrayList 结合 JAVA 源码,我们可以看到 Vector 和 ArrayList 都是基于数组实现的,都继承自 List 接口。因此他们随机查询的效率是非常高的,但是他们在数据插入或删除,以及需要扩容的时候效率都比较低下,需要在原有数组之外进行复制、移动。还有一点细节的区别在于扩容的默认值,ArrayList 在内存不足时默认扩容至 1.5 倍再加 1 个,Vector 默认扩容为原来的 2 倍。他们最重要的区别在于 Vector 中大量使用了 synchronized 来修饰方法,所以它是线程安全的,相应的,效率也是比 ArrayList 更低的。所以我们生成今天的第一条结论:需要线程安全的场景使用Vector。
- 3.1 泛型使用 在代码中,这样使用泛型:List<String> list = new ArrayList<String>();// Java 7 及以后的版本中,构造方法中可以省略泛型类型:List<String> list = new ArrayList<>();要注意的是,变量声明的类型必须与传递给实际对象的类型保持一致,下面是错误的例子:List<Object> list = new ArrayList<String>();List<Number> numbers = new ArrayList(Integer);
- 2. 为什么需要泛型 上一节中,我们在使用ArrayList实现类的时候,如果没有指定泛型,IDEA会给出警告,代码似乎也是可以顺利运行的。请看如下实例:import java.util.ArrayList;public class GenericsDemo1 { public static void main(String[] args) { ArrayList arrayList = new ArrayList(); arrayList.add("Hello"); String str = (String) arrayList.get(0); System.out.println("str=" + str); }}运行结果:str=Hello虽然运行时没有发生任何异常,但这样做有两个缺点:需要强制类型转换: 由于ArrayList内部就是一个Object[]数组,在get()元素的时候,返回的是Object类型,所以在ArrayList外获取该对象,需要强制类型转换。其它的Collection、Map如果不使用泛型,也存在这个问题;可向集合中添加任意类型的对象,存在类型不安全风险。例如如下代码中,我们向列表中既添加了Integer类型,又添加了String类型:import java.util.ArrayList;public class GenericsDemo2 { public static void main(String[] args) { ArrayList arrayList = new ArrayList(); arrayList.add(123); arrayList.add("Hello"); String str = (String) arrayList.get(0); System.out.println("element=" + str); }}运行结果:Exception in thread "main" java.lang.ClassCastException: class java.lang.Integer cannot be cast to class java.lang.String (java.lang.Integer and java.lang.String are in module java.base of loader 'bootstrap') at GenericsDemo2.main(GenericsDemo2.java:8)由于我们的“疏忽”,列表第 1 个元素实际上是整型,但被我们强制转换为字符串类型,这是行不通的,因此会抛出ClassCastException异常。使用泛型可以解决这些问题。泛型有如下优点:可以减少类型转换的次数,代码更加简洁;程序更加健壮:只要编译期没有警告,运行期就不会抛出ClassCastException异常;提高了代码的可读性:编写集合的时候,就限定了集合中能存放的类型。
- 6.4 集合的初始化 由于在 Kotlin 中集合主要分为了只读集合和可变集合,那么初始化只读集合和可变集合的函数也不一样。以 List 集合为例,对于只读集合初始化一般采用listOf()方法,对于可变集合初始化一般采用mutableListOf()或者直接创建 ArrayList<E>。因为 mutableListOf() 内部实现也是也还是采用创建ArrayList,这个 ArrayList 实际上是 Java 中的 java.util.ArrayList<E>,只不过在 Kotlin 中使用 typealias (关于 typealias 的使用之前有过详细介绍)取了别名而已。关于具体内容请参考这个类kotlin.collections.TypeAliasesKt实现。
arraylist相关搜索
-
ajax
android
a href
abap
abap开发
abort
absolutelayout
abstractmethoderror
abstracttablemodel
accept
access
access教程
accordion
accumulate
acess
action
actionform
actionlistener
activity
addeventlistener