Java中集合是一个为集合提供了单独的类,在开发中经常使用,并且面试中也经常在这里设置问题。本篇就总体上说下Java中的集合和从JDK源码上分析下List这种集合。
0.集合的分类
Java中在java.util包中为集合提供了List,Set,Map等
Java 集合框架主要包括两种类型的容器,一种是集合(Collection),存储一个元素集合,另一种是图(Map),存储键/值对映射。
我们来看一下集合的框架图。
看起来挺乱的…目前看这个图有个印象就行,我们一点一点来分析…这篇我们主要说说List。
1.List简介
List的年头也是相当长的早在JDK1.2就出现了。
List和数组类似,可以动态增长,根据实际存储的数据的长度自动增长List的长度。
就结构上来说List是个接口继承至Collection接口,需要实现类。
public interface List<E> extends Collection<E>
2.List主要实现类
从图中就可以看出来List的主要实现类有Vector(),ArrayList(),LinkedList()。
Vector(): 底层是数组,查询快,增删慢,线程安全,效率低下已经不建议使用。
ArrayList(): 底层是数组,查询快,增删慢,线程不安全,高效。
LinkedList(): 底层是链表,查询慢,增删快,线程不安全,高效。
下面我们队ArrayList(),和LinkedList()深入了解下
3.ArrayList()
ArrayList是可以动态增长和缩减的索引序列,该类封装了一个动态再分配的Object[]数组。
ArrayList()线程不安全所以在多线程访问同一个ArrayList时为保证集合的同步性记得加锁。
部分JDK源码
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
private static final int DEFAULT_CAPACITY = 10;//默认初始容量10
private int size;//实际数据数量,"."出来的size是方法,这个是变量。
//当由于增加数据导致容量不足时,容量会添加上一次容量大小的一半。
public ArrayList(int initialCapacity) //带初额始容量大小的构造函数,看z这个函数怎么写的能看出什么叫程序的健壮性。
public ArrayList() //无参构造函数,默认容量为10
public ArrayList(Collection<? extends E> c) //创建一个包含collection的ArrayList
public int size() //返回ArrayList的大小
public boolean isEmpty() //判断ArrayList是否为空
public boolean contains(Object o) //判断ArrayList中是否包含Object(o)
public int indexOf(Object o) //正向查找,返回ArrayList中元素Object(o)的索引位置
public int lastIndexOf(Object o) //逆向查找,返回返回ArrayList中元素Object(o)的索引位置
public E remove(int index)//删除ArrayList指定位置的元素
private void fastRemove(int index)//快速删除指定位置的元素
public void clear() //清空ArrayList,将全部的元素设为null
...
}
这里的方法是不少…有兴趣的朋友可以查找相关文档,或自行查看JDK源码。
看看怎么用吧
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ArrayListtest {
public static void main(String[] args){
List<String> list=new ArrayList<String>();
//添加元素
list.add("Hello");
list.add("World");
list.add("AAA");
list.add("BBB");
list.add("AAA");
System.out.println(list);//[Hello, World, AAA, BBB, AAA]
//insert(int index,object value)
//将元素插入到索引处(不过其有一定的限制性,必须在数组长度以内插入数组)
list.add(1,"Our");//添加到索引“1”的位置
System.out.println(list);//[Hello, Our, World, AAA, BBB, AAA]
//删除元素
list.remove("AAA");//移除数组中的第一个"AAA"元素
System.out.println(list);//[Hello, Our, World, BBB, AAA]
list.remove(0);
System.out.println(list);//[Our, World, BBB, AAA]
//list.RemoveRange(int indext,int count);//移除从索引index开始,移除count个元素
//查找元素
System.out.println(list.contains("BBB"));//查找数组中是否有obj元素,返回类型为boolean存在返回true;
/*
* list.IndexOf(object obj, int startIndex); //从startIndex开始查找obj元素,只第一个obj元素,并返回起在数组中的位置,
* list.IndexOf(object obj, int startIndex, int count); //从startIndex开始想后查找count个元素,如果存在obj元素,则返回其在数组中的位置
*/
//获取元素
System.out.println(list.get(0));//[Our, World, BBB, AAA]
//数组长度
System.out.println(list.size());//[Our, World, BBB, AAA]
//判断是否为空
System.out.println(list.isEmpty());//[Our, World, BBB, AAA]
//foreach循环
for (String str : list) {//for(int i=0;i<list.size();i++){String str = list.get(i);}
System.out.println(str);
}
//迭代器遍历
Iterator<String> ite=list.iterator();
while(ite.hasNext())//判断下一个元素之后有值
{
System.out.println(ite.next());
}
list.clear();//清空
System.out.println(list.isEmpty());
}
}
运行结果:
[Hello, World, AAA, BBB, AAA]
[Hello, Our, World, AAA, BBB, AAA]
[Hello, Our, World, BBB, AAA]
[Our, World, BBB, AAA]
true
Our
4
false
Our
World
BBB
AAA
Our
World
BBB
AAA
true
OK,ArrayList就到这里了。
3.LinkedList()
LinkedList也是一个列表,它实现了双向链表,每个数据结点中都有三个数据项:前节点的引用(Previous Node)、本节点元素(Node Element)、后继节点的引用(Next Node)。
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{
transient int size = 0;
transient Node<E> first;
transient Node<E> last;
}
看JDK源码就就可以看出来LinkedList(),是双向链表实现的,用起来感觉上效果和ArrayList()在小数据量上差别并不大。