Java中集合是一个为集合提供了单独的类,在开发中经常使用,并且面试中也经常在这里设置问题。本篇就总体上说下Java中的集合和从JDK源码上分析下List这种集合。

0.集合的分类

Java中在java.util包中为集合提供了ListSetMap

Java 集合框架主要包括两种类型的容器,一种是集合(Collection),存储一个元素集合,另一种是图(Map),存储键/值对映射。

我们来看一下集合的框架图。

java对List 进行groupBy java list 集合_Java


看起来挺乱的…目前看这个图有个印象就行,我们一点一点来分析…这篇我们主要说说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()在小数据量上差别并不大。