- 浏览: 257147 次
- 性别:
- 来自: 北京
-
博客专栏
-
-
Java并发包源码解析
浏览量:101837
最新评论
-
746238836:
整个RingBuffer内部做了大量的缓存行填充,前后各填充了 ...
disruptor-3.3.2源码解析(2)-队列 -
xiangshouxiyang:
群加不了。。。
Jdk1.7 ForkJoin框架源码解析汇总 -
有贝无患:
acquire方法里面为什么tryAcquire会被调用多次 ...
Jdk1.6 JUC源码解析(6)-locks-AbstractQueuedSynchronizer -
zwy_qz:
library_call.cpp 里面的内联操作 inline ...
Jdk1.6 JUC源码解析(1)-atomic-AtomicXXX -
sunwang810812:
您好,正在学习您的文章,中间有一段,一直没明白:“privat ...
Jdk1.6 JUC源码解析(6)-locks-AbstractQueuedSynchronizer
工作中经常会用到Java的集合类,最近不忙了,把相关知识总结一下,便于理解记忆。
打开java.util.ArrayList的源代码,首先映入眼帘的是@author Josh Bloch(相对于源码,本人更喜欢看故事
,每次看到一份源码,先看看作者是谁。然后搜索一下作者的百科以及一些八卦。。。以及与作者相关的人的百科和一些八卦。。。以及。。。一上午就过去了。。。
言归正传,看一个类的时候首先要看看这个类能干什么,有什么特性。这些都可以在这个类实现的接口上体现了(废话。。。)。好,直接从最顶级的接口看吧。首先是接口java.lang.Iterable:
由于篇幅的关系,去掉了注释。注释上说明,实现了这个接口的类,可以使用"foreach"语法。
接下来是接口java.util.Collection:
里面的注释很详细,反正大概意思是说(英语不太好),这是集合层次的顶级接口,代表了一组对象blablablabla,所有通用的实现应该提供两个"标准"的构造方法:无参的构造方法和拥有一个集合类型参数的构造方法blablablabla,总之这个接口对集合进行了高度滴、抽象滴定义:)
接下来就是java.util.List接口了。
list代表了一个有序的集合,可以通过index来访问和查找集合内的元素,集合内元素是可重复的,因为index(集合中的位置)不同。
还有一个ArrayList实现的接口是java.util.RandomAccess:
一看没有方法的接口,就知道这大概是个标记接口喽。实现这个接口的集合类会在随机访问元素上提供很好的性能。比如说,ArrayList实现了RandomAccess而LinkedList没有,那么当我们拿到一个集合时(假设这个集合不是ArrayList就是LinkedList),如果这个集合时ArrayList,那么我们遍历集合元素可以使用下标遍历,如果是LinkedList,就使用迭代器遍历。比如集合工具类Collections中提供的对集合中元素进行二分查找的方法,代码片段如下:
还有java.lang.Cloneable和java.io.Serializable两个标记接口,表示ArrayList是可克隆的、可序列化的。
还要看一下AbstractCollection和AbstractList,这两个抽象类里实现了一部分公共的功能,代码都还比较容易看懂。
需要注意的地方是AbstractList中的一个属性modCount。这个属性主要由集合的迭代器来使用,对于List来说,可以调用iterator()和listIterator()等方法来生成一个迭代器,这个迭代器在生成时会将List的modCount保存起来(迭代器实现为List的内部类),在迭代过程中会去检查当前list的modCount是否发生了变化(和自己保存的进行比较),如果发生变化,那么马上抛出java.util.ConcurrentModificationException异常,这种行为就是fail-fast。
好了,终于可以看ArrayList了,在看之前可以先思考一下,如果我们自己来实现ArrayList,要怎么实现。我们都会把ArrayList简单的看作动态数组,说明我们使用它的时候大都是当做数组来使用的,只不过它的长度是可改变的。那我们的问题就变成了一个实现长度可变化的数组的问题了。那么首先,我们会用一个数组来做底层数据存储的结构,新建的时候会提供一个默认的数组长度。当我们添加或删除元素的时候,会改变数据的长度(当默认长度不够或者其他情况下),这里涉及到数据的拷贝,我们可以使用系统提供的System.arraycopy来进行数组拷贝。如果我们每次添加或者删除元素时都会因为改变数组长度而拷贝数组,那也太2了,可以在当数组长度不够的时候,扩展一定的空间,比如可以扩展到原来的2倍,这样会提高一点性能(如果不是在数组末尾添加或删除元素的话,还是会进行数组拷贝),但同时浪费了一点空间。再看看上面的接口,比如我们要实现size方法,那么就不能直接返回数组的长度了(由于上面的原因),也没办法去遍历数组得到长度(因为可能存在null元素),我们会想到利用一个私有变量来保存长度,在添加删除等方法里面去相应修改这个变量(这里不考虑线程安全问题,因为ArrayList本身就不是线程安全的)。
带着这些问题,来看一下ArrayList的代码。
首先,真正存储元素的是一个数组。
那么这个数组该怎么初始化呢?数组的长度该怎么确定呢?看一下构造方法。
可以看到,我们可以选择使用一个参数作为ArrayList内部数组的容量来构造一个ArrayList;或者使用无参的构造方法,这样会默认使用10作为数组容量。我们在实际应用中可以根据具体情况来选择使用哪个构造方法,例如在某种特定逻辑下,我们需要存储200个元素(固定值)到一个ArrayList里,那我们就可以使用带一个int型参数的构造方法,这样就避免了在数组长度不够,进行扩容时,内部数组的拷贝。
当然,根据接口java.util.Collection的规范(非强制),ArrayList也提供用一个集合做为参数的构造方法。
上面说到说考虑用一个私有变量来存储size(集合中实际原始的个数)。在ArrayList也有这样一个变量。
有了这个变量,一些方法实现起来就非常简单了。
由于内部数组的存在,一些基于下标的方法实现起来也非常简单。
有几个要注意的地方,首先是RangeCheck方法,顾名思义是做边界检查的,看看方法实现。
异常信息是不是很眼熟,呵呵。
还有就是在"添加"方法中的ensureCapacity方法,上面也考虑到扩容的问题,这个方法其实就干了这件事情。
注意当数组长度不够的时候,会进行数组的扩展,扩展到原来长度的1.5倍(注意整型的除法)加1,比如原来是2,会扩展到4,原来是30,会扩展到46。当数组的长度大到算出的新容量超出了整型最大范围,那么新容量就等于传入的"最小容量"。
最后再看一下另一个删除方法。
可以看到,像size、isEmpty、get、set这样的方法时间复杂度为O(1),而像indexOf、add、remove等方法,最坏的情况下(如添加元素到第一个位置,删除第一个位置的元素,找最后一个元素的下标等)时间复杂度为O(n)。
一般情况下内部数组的长度总是大于集合中元素总个数的,ArrayList也提供了一个释放多余空间的方法,我们可以适时调用此方法来减少内存占用。
基本上ArrayList的内容总结的差不多啦。最后,别忘了它是线程不安全的。
是的,确实有一些歧义,让人感觉里面的元素是按某种方式排序的。
当时是参考了list接口的注释:An ordered collection。
就是那种有序集合喽,你懂得。
打开java.util.ArrayList的源代码,首先映入眼帘的是@author Josh Bloch(相对于源码,本人更喜欢看故事

言归正传,看一个类的时候首先要看看这个类能干什么,有什么特性。这些都可以在这个类实现的接口上体现了(废话。。。)。好,直接从最顶级的接口看吧。首先是接口java.lang.Iterable:
package java.lang; import java.util.Iterator; public interface Iterable<T> { Iterator<T> iterator(); }
由于篇幅的关系,去掉了注释。注释上说明,实现了这个接口的类,可以使用"foreach"语法。
接下来是接口java.util.Collection:
package java.util; public interface Collection<E> extends Iterable<E> { int size(); boolean isEmpty(); boolean contains(Object o); Iterator<E> iterator(); Object[] toArray(); <T> T[] toArray(T[] a); boolean add(E e); boolean remove(Object o); boolean containsAll(Collection<?> c); boolean addAll(Collection<? extends E> c); boolean removeAll(Collection<?> c); boolean retainAll(Collection<?> c); void clear(); boolean equals(Object o); int hashCode(); }
里面的注释很详细,反正大概意思是说(英语不太好),这是集合层次的顶级接口,代表了一组对象blablablabla,所有通用的实现应该提供两个"标准"的构造方法:无参的构造方法和拥有一个集合类型参数的构造方法blablablabla,总之这个接口对集合进行了高度滴、抽象滴定义:)
接下来就是java.util.List接口了。
public interface List<E> extends Collection<E> { //和Collection重复的方法就不贴了,但必须知道有这些方法 boolean addAll(int index, Collection<? extends E> c); E get(int index); E set(int index, E element); void add(int index, E element); E remove(int index); int indexOf(Object o); int lastIndexOf(Object o); ListIterator<E> listIterator(); ListIterator<E> listIterator(int index); List<E> subList(int fromIndex, int toIndex); }
list代表了一个有序的集合,可以通过index来访问和查找集合内的元素,集合内元素是可重复的,因为index(集合中的位置)不同。
还有一个ArrayList实现的接口是java.util.RandomAccess:
package java.util; public interface RandomAccess { }
一看没有方法的接口,就知道这大概是个标记接口喽。实现这个接口的集合类会在随机访问元素上提供很好的性能。比如说,ArrayList实现了RandomAccess而LinkedList没有,那么当我们拿到一个集合时(假设这个集合不是ArrayList就是LinkedList),如果这个集合时ArrayList,那么我们遍历集合元素可以使用下标遍历,如果是LinkedList,就使用迭代器遍历。比如集合工具类Collections中提供的对集合中元素进行二分查找的方法,代码片段如下:
public static <T> int binarySearch(List<? extends Comparable<? super T>> list, T key) { if (list instanceof RandomAccess || list.size()<BINARYSEARCH_THRESHOLD) return Collections.indexedBinarySearch(list, key); else return Collections.iteratorBinarySearch(list, key); }
还有java.lang.Cloneable和java.io.Serializable两个标记接口,表示ArrayList是可克隆的、可序列化的。
还要看一下AbstractCollection和AbstractList,这两个抽象类里实现了一部分公共的功能,代码都还比较容易看懂。
需要注意的地方是AbstractList中的一个属性modCount。这个属性主要由集合的迭代器来使用,对于List来说,可以调用iterator()和listIterator()等方法来生成一个迭代器,这个迭代器在生成时会将List的modCount保存起来(迭代器实现为List的内部类),在迭代过程中会去检查当前list的modCount是否发生了变化(和自己保存的进行比较),如果发生变化,那么马上抛出java.util.ConcurrentModificationException异常,这种行为就是fail-fast。
好了,终于可以看ArrayList了,在看之前可以先思考一下,如果我们自己来实现ArrayList,要怎么实现。我们都会把ArrayList简单的看作动态数组,说明我们使用它的时候大都是当做数组来使用的,只不过它的长度是可改变的。那我们的问题就变成了一个实现长度可变化的数组的问题了。那么首先,我们会用一个数组来做底层数据存储的结构,新建的时候会提供一个默认的数组长度。当我们添加或删除元素的时候,会改变数据的长度(当默认长度不够或者其他情况下),这里涉及到数据的拷贝,我们可以使用系统提供的System.arraycopy来进行数组拷贝。如果我们每次添加或者删除元素时都会因为改变数组长度而拷贝数组,那也太2了,可以在当数组长度不够的时候,扩展一定的空间,比如可以扩展到原来的2倍,这样会提高一点性能(如果不是在数组末尾添加或删除元素的话,还是会进行数组拷贝),但同时浪费了一点空间。再看看上面的接口,比如我们要实现size方法,那么就不能直接返回数组的长度了(由于上面的原因),也没办法去遍历数组得到长度(因为可能存在null元素),我们会想到利用一个私有变量来保存长度,在添加删除等方法里面去相应修改这个变量(这里不考虑线程安全问题,因为ArrayList本身就不是线程安全的)。
带着这些问题,来看一下ArrayList的代码。
首先,真正存储元素的是一个数组。
/** * The array buffer into which the elements of the ArrayList are stored. * The capacity of the ArrayList is the length of this array buffer. */ private transient Object[] elementData;
那么这个数组该怎么初始化呢?数组的长度该怎么确定呢?看一下构造方法。
/** * Constructs an empty list with the specified initial capacity. * * @param initialCapacity the initial capacity of the list * @exception IllegalArgumentException if the specified initial capacity * is negative */ public ArrayList(int initialCapacity) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); this.elementData = new Object[initialCapacity]; } /** * Constructs an empty list with an initial capacity of ten. */ public ArrayList() { this(10); }
可以看到,我们可以选择使用一个参数作为ArrayList内部数组的容量来构造一个ArrayList;或者使用无参的构造方法,这样会默认使用10作为数组容量。我们在实际应用中可以根据具体情况来选择使用哪个构造方法,例如在某种特定逻辑下,我们需要存储200个元素(固定值)到一个ArrayList里,那我们就可以使用带一个int型参数的构造方法,这样就避免了在数组长度不够,进行扩容时,内部数组的拷贝。
当然,根据接口java.util.Collection的规范(非强制),ArrayList也提供用一个集合做为参数的构造方法。
/** * Constructs a list containing the elements of the specified * collection, in the order they are returned by the collection's * iterator. * * @param c the collection whose elements are to be placed into this list * @throws NullPointerException if the specified collection is null */ public ArrayList(Collection<? extends E> c) { elementData = c.toArray(); size = elementData.length; // c.toArray might (incorrectly) not return Object[] (see 6260652) if (elementData.getClass() != Object[].class) elementData = Arrays.copyOf(elementData, size, Object[].class); }
上面说到说考虑用一个私有变量来存储size(集合中实际原始的个数)。在ArrayList也有这样一个变量。
/** * The size of the ArrayList (the number of elements it contains). * * @serial */ private int size;
有了这个变量,一些方法实现起来就非常简单了。
/** * Returns the number of elements in this list. * * @return the number of elements in this list */ public int size() { return size; } /** * Returns <tt>true</tt> if this list contains no elements. * * @return <tt>true</tt> if this list contains no elements */ public boolean isEmpty() { return size == 0; } /** * Returns <tt>true</tt> if this list contains the specified element. * More formally, returns <tt>true</tt> if and only if this list contains * at least one element <tt>e</tt> such that * <tt>(o==null ? e==null : o.equals(e))</tt>. * * @param o element whose presence in this list is to be tested * @return <tt>true</tt> if this list contains the specified element */ public boolean contains(Object o) { return indexOf(o) >= 0; } /** * Returns the index of the first occurrence of the specified element * in this list, or -1 if this list does not contain the element. * More formally, returns the lowest index <tt>i</tt> such that * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>, * or -1 if there is no such index. */ public int indexOf(Object o) { if (o == null) { for (int i = 0; i < size; i++) if (elementData[i]==null) return i; } else { for (int i = 0; i < size; i++) if (o.equals(elementData[i])) return i; } return -1; } /** * Returns the index of the last occurrence of the specified element * in this list, or -1 if this list does not contain the element. * More formally, returns the highest index <tt>i</tt> such that * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>, * or -1 if there is no such index. */ public int lastIndexOf(Object o) { if (o == null) { for (int i = size-1; i >= 0; i--) if (elementData[i]==null) return i; } else { for (int i = size-1; i >= 0; i--) if (o.equals(elementData[i])) return i; } return -1; }
由于内部数组的存在,一些基于下标的方法实现起来也非常简单。
/** * Returns the element at the specified position in this list. * * @param index index of the element to return * @return the element at the specified position in this list * @throws IndexOutOfBoundsException {@inheritDoc} */ public E get(int index) { RangeCheck(index); return (E) elementData[index]; } /** * Replaces the element at the specified position in this list with * the specified element. * * @param index index of the element to replace * @param element element to be stored at the specified position * @return the element previously at the specified position * @throws IndexOutOfBoundsException {@inheritDoc} */ public E set(int index, E element) { RangeCheck(index); E oldValue = (E) elementData[index]; elementData[index] = element; return oldValue; } /** * Appends the specified element to the end of this list. * * @param e element to be appended to this list * @return <tt>true</tt> (as specified by {@link Collection#add}) */ public boolean add(E e) { ensureCapacity(size + 1); // Increments modCount!! elementData[size++] = e; return true; } /** * Inserts the specified element at the specified position in this * list. Shifts the element currently at that position (if any) and * any subsequent elements to the right (adds one to their indices). * * @param index index at which the specified element is to be inserted * @param element element to be inserted * @throws IndexOutOfBoundsException {@inheritDoc} */ public void add(int index, E element) { if (index > size || index < 0) throw new IndexOutOfBoundsException( "Index: "+index+", Size: "+size); ensureCapacity(size+1); // Increments modCount!! System.arraycopy(elementData, index, elementData, index + 1, size - index); elementData[index] = element; size++; } /** * Removes the element at the specified position in this list. * Shifts any subsequent elements to the left (subtracts one from their * indices). * * @param index the index of the element to be removed * @return the element that was removed from the list * @throws IndexOutOfBoundsException {@inheritDoc} */ public E remove(int index) { RangeCheck(index); modCount++; E oldValue = (E) elementData[index]; int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // Let gc do its work return oldValue; }
有几个要注意的地方,首先是RangeCheck方法,顾名思义是做边界检查的,看看方法实现。
/** * Checks if the given index is in range. If not, throws an appropriate * runtime exception. This method does *not* check if the index is * negative: It is always used immediately prior to an array access, * which throws an ArrayIndexOutOfBoundsException if index is negative. */ private void RangeCheck(int index) { if (index >= size) throw new IndexOutOfBoundsException( "Index: "+index+", Size: "+size); }
异常信息是不是很眼熟,呵呵。
还有就是在"添加"方法中的ensureCapacity方法,上面也考虑到扩容的问题,这个方法其实就干了这件事情。
/** * Increases the capacity of this <tt>ArrayList</tt> instance, if * necessary, to ensure that it can hold at least the number of elements * specified by the minimum capacity argument. * * @param minCapacity the desired minimum capacity */ public void ensureCapacity(int minCapacity) { modCount++; int oldCapacity = elementData.length; if (minCapacity > oldCapacity) { Object oldData[] = elementData; int newCapacity = (oldCapacity * 3)/2 + 1; if (newCapacity < minCapacity) newCapacity = minCapacity; // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); } }
注意当数组长度不够的时候,会进行数组的扩展,扩展到原来长度的1.5倍(注意整型的除法)加1,比如原来是2,会扩展到4,原来是30,会扩展到46。当数组的长度大到算出的新容量超出了整型最大范围,那么新容量就等于传入的"最小容量"。
最后再看一下另一个删除方法。
/** * Removes the first occurrence of the specified element from this list, * if it is present. If the list does not contain the element, it is * unchanged. More formally, removes the element with the lowest index * <tt>i</tt> such that * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt> * (if such an element exists). Returns <tt>true</tt> if this list * contained the specified element (or equivalently, if this list * changed as a result of the call). * * @param o element to be removed from this list, if present * @return <tt>true</tt> if this list contained the specified element */ public boolean remove(Object o) { if (o == null) { for (int index = 0; index < size; index++) if (elementData[index] == null) { fastRemove(index); return true; } } else { for (int index = 0; index < size; index++) if (o.equals(elementData[index])) { fastRemove(index); return true; } } return false; } /* * Private remove method that skips bounds checking and does not * return the value removed. */ private void fastRemove(int index) { modCount++; int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // Let gc do its work }
可以看到,像size、isEmpty、get、set这样的方法时间复杂度为O(1),而像indexOf、add、remove等方法,最坏的情况下(如添加元素到第一个位置,删除第一个位置的元素,找最后一个元素的下标等)时间复杂度为O(n)。
一般情况下内部数组的长度总是大于集合中元素总个数的,ArrayList也提供了一个释放多余空间的方法,我们可以适时调用此方法来减少内存占用。
/** * Trims the capacity of this <tt>ArrayList</tt> instance to be the * list's current size. An application can use this operation to minimize * the storage of an <tt>ArrayList</tt> instance. */ public void trimToSize() { modCount++; int oldCapacity = elementData.length; if (size < oldCapacity) { elementData = Arrays.copyOf(elementData, size); } }
基本上ArrayList的内容总结的差不多啦。最后,别忘了它是线程不安全的。
评论
2 楼
BrokenDreams
2015-12-27
carlosfu 写道
list是有序集合,是不是不太恰当
集合一般是说没有重复的元素,吹毛求疵了,我

集合一般是说没有重复的元素,吹毛求疵了,我

是的,确实有一些歧义,让人感觉里面的元素是按某种方式排序的。
当时是参考了list接口的注释:An ordered collection。
就是那种有序集合喽,你懂得。

1 楼
carlosfu
2015-12-24
list是有序集合,是不是不太恰当
集合一般是说没有重复的元素,吹毛求疵了,我

集合一般是说没有重复的元素,吹毛求疵了,我

发表评论
-
Jdk1.6 Collections Framework源码解析(12)-TreeMap、TreeSet
2016-01-03 16:06 2185Jdk1.6 Collections Framework ... -
Jdk1.6 Collections Framework源码解析(11)-EnumSet
2015-12-29 18:25 1891Jdk1.6 Collections Framework源 ... -
Jdk1.6 JUC源码解析(26)-ConcurrentSkipListMap、ConcurrentSkipListSet
2015-11-03 03:08 5407Jdk1.6 JUC源码解析(26)-Concurrent ... -
Jdk1.6 JUC源码解析(25)-ConcurrentHashMap
2015-10-30 19:02 2564Jdk1.6 JUC源码解析(25)-Co ... -
Jdk1.6 集合框架源码解析汇总
2015-10-29 22:05 3495Jdk1.6 集合框架源码解析汇总 非并发: ... -
Jdk1.6 JUC源码解析(24)-ConcurrentLinkedQueue
2015-10-29 19:02 1938Jdk1.6 JUC源码解析(24)-ConcurrentL ... -
Jdk1.6 JUC源码解析(23)-CopyOnWriteArrayList、CopyOnWriteArraySet
2015-10-29 18:55 1847Jdk1.6 JUC源码解析(23)-Cop ... -
Jdk1.6 JUC源码解析(22)-LinkedBlockingDeque
2015-10-29 18:47 1636Jdk1.6 JUC源码解析(22)-LinkedBloc ... -
Jdk1.6 JUC源码解析(18)-DelayQueue
2015-10-27 19:25 2413Jdk1.6 JUC源码解析(18)-DelayQueue ... -
Jdk1.6 JUC源码解析(15)-SynchronousQueue
2015-10-26 19:19 2600Jdk1.6 JUC源码解析(15)-Synchronou ... -
Jdk1.6 JUC源码解析(14)-PriorityBlockingQueue
2015-10-25 03:22 2352Jdk1.6 JUC源码解析(14)-Pr ... -
Jdk1.6 JUC源码解析(13)-LinkedBlockingQueue
2015-10-24 22:28 1850Jdk1.6 JUC源码解析(13)-LinkedBloc ... -
Jdk1.6 JUC源码解析(12)-ArrayBlockingQueue
2015-10-23 20:03 2213Jdk1.6 JUC源码解析(12)-Ar ... -
Jdk1.6 Collections Framework源码解析(10)-EnumMap
2013-09-09 14:55 1503看这个类之前,先看一下Java的枚举——Enu ... -
Jdk1.6 Collections Framework源码解析(9)-PriorityQueue
2013-09-03 20:37 2105开发中有时会遇到这样的情况。要求某个调度器去调 ... -
Jdk1.6 Collections Framework源码解析(8)-WeakHashMap
2013-09-02 11:43 2189总结这个类之前,首先看一下Java引用的相关知 ... -
Jdk1.6 Collections Framework源码解析(7)-HashSet、LinkedHashSet
2013-08-28 11:34 1676本篇总结一 ... -
Jdk1.6 Collections Framework源码解析(6)-IdentityHashMap
2013-08-27 14:10 1628这篇总结一下java.util.Identit ... -
Jdk1.6 Collections Framework源码解析(5)-LinkedHashMap
2013-08-20 14:28 1816前面总结了java.util.HashMap, ... -
Jdk1.6 Collections Framework源码解析(4)-HashMap
2013-08-19 13:59 2045开发中常常 ...
相关推荐
《Jdk1.6 Collections Framework源码解析(2)-LinkedList》 LinkedList是Java集合框架中的一个重要的类,它是List接口的实现,同时继承了AbstractSequentialList,并实现了Deque接口。LinkedList是一种双链表结构,...
1. **基础类库**:如集合框架(Collections Framework)、I/O流、网络编程、多线程等,这些都是构建任何Java应用程序的基础。 2. **Java Swing**:Java 1.6中包含的GUI(图形用户界面)库,用于创建桌面应用程序,...
### Java Collections Framework 知识点概览 #### 一、教程导引与适用对象 - **教程概述**:本教程由 developerWorks 提供,旨在帮助读者深入理解 Java Collections Framework 的各个方面。 - **适用人群**: - *...
- **集合框架(Collections Framework)**:包括List、Set、Map等接口,以及ArrayList、LinkedList、HashSet、HashMap等实现类,为数据存储和操作提供了强大支持。例如,ArrayList提供了动态数组功能,HashMap则提供...
此资源——"JDK-1-6中文API",是Java程序员的重要参考资料,特别是对于初学者,它提供了一份详尽的中文文档,便于理解和应用Java的各种类库。 API(Application Programming Interface)是一系列预先定义的函数,...
Java Collections Framework包括了ArrayList、LinkedList、HashSet、TreeSet等多种集合类,每种集合类都提供了不同的功能和性能特点。 Java Streams API Java Streams API是Java核心库的一个重要组件,提供了高效...
2. **集合框架( Collections Framework)** - JDK8对集合框架进行了重大改进,引入了Stream API,使得数据处理更加高效和简洁。例如,`List`, `Set`, `Map`的实现类如ArrayList、HashSet、HashMap等的源码揭示了它们...
对于 JDK 1.1 用户,本书还讨论了如何使用 Java Collection Framework 的子集。此外,还介绍了一种名为 JGL (Java Generic Library) 的第三方库,该库在 Java Collection Framework 出现之前就已经存在,并且提供了...
3. **集合框架(Collections Framework)**: - `java.util`包中的ArrayList、LinkedList、HashMap、HashSet等实现了各种数据结构,理解它们的内部实现对于优化性能至关重要。比如,HashMap的哈希算法和扩容策略,...
6. **集合框架(Collections Framework)**:Java集合框架是处理对象集合的核心,包括List、Set、Map等接口以及它们的实现类。`java.util`和`java.util.concurrent`包中的类实现了各种数据结构和算法,为高效的数据...
例如,开发者可以学习如何使用集合框架(Collections Framework),如ArrayList、HashMap等,了解并发编程工具,如ExecutorService和Future,以及如何使用I/O和网络API进行数据传输。 对于Java初学者,这些文档是不...
JDK 7对集合框架进行了优化,例如`Arrays.asList()`方法现在能直接接收变长参数,`Collections.addAll()`方法也有了类似的改进。另外,`Map`接口新增了`putIfAbsent()`、`remove()`和`replace()`等原子操作方法,...
2. 集合框架(Collections Framework):如ArrayList、LinkedList、HashMap等数据结构的实现,以及它们的性能特点。 3. 多线程(Thread):深入研究线程的创建、同步、唤醒、阻塞等操作的底层实现。 4. 异常处理...
1. **泛型类型推断(Type Inference for Generic Instance Creation)**:在JDK 7中,你可以使用"钻石操作符"()来简化创建泛型实例的代码,例如`List<String> list = new ArrayList();`,编译器会自动推断出泛型...
其中包括了各种核心类、接口、枚举和异常,如集合框架(Collections Framework)、I/O流(IO Streams)、多线程(Multithreading)、网络编程(Networking)、反射(Reflection)、XML处理(XML Processing)等。...
8. **类型安全的异构容器(Collections Framework增强)**:集合框架进行了改进,如ArrayList和LinkedList等实现了Iterable接口,Map接口新增了entrySet()方法,方便遍历。 9. **死锁检测(Thread API增强)**:JDK...
4. **集合框架(Java Collections Framework)**:包括ArrayList、LinkedList、HashMap等常用数据结构的实现,理解它们的内部结构和操作逻辑,有助于编写高效代码。 5. **多线程(Multithreading)**:Java对多线程的...
7. **集合框架(Collections Framework)**:`java.util`包中的ArrayList、LinkedList、HashMap、TreeMap等实现了各种数据结构,源码可以揭示它们的底层实现和性能特点。 8. **I/O流(Input/Output Streams)**:`...
在JDK源码阅读Collection详解中,我们可以看到Collection接口的实现类有很多,如ArrayList、LinkedList、HashSet、TreeSet等。这些实现类都继承了Collection接口,并实现了其定义的方法。 在实际开发中,我们经常...
除此之外,JDK1.5 API还涵盖了Java的核心类库,包括集合框架(Collections Framework)、输入/输出(I/O)、网络编程、多线程、反射、异常处理、国际化等多个方面。集合框架中的List、Set、Map接口及其实现类如...