容器框架
Java的容器框架提供了一套性能优良、使用方便的接口和类,他们位于java.util包中。
存放在集合中的数组,被称为元素(element)
Collection接口
Collection接口中的方法
他有两个子接口:List和Set。
各个接口的特点:
Collection接口存储一组不唯一,无序的对象 List接口存储一组不唯一,可重复的有序(索引顺序)的对象 Set接口存储一组唯一,无序的对象
List接口_ArrayList_用法详解
ArrayList的用法
package cn.xjion.pro09;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Scanner;
public class TestArrayList {
public static void main(String[] args) {
// 创建对象
List list = new ArrayList();
// 添加数据
list.add("hello");
list.add(9090980);//会自动装箱
list.add(new Scanner(System.in));//控制台
// 集合中元素的个数size
System.out.println(list.size());
System.out.println("集合是否为空:"+list.isEmpty());
List list2 = new ArrayList();
list2.add("hello");
list.add(9090980);
// addAll(Collection c)
list.addAll(list2);
System.out.println("list集合中的元素的个数:"+list);
System.out.println(list);
// 删除remove
System.out.println("根据对象来删除");
list.remove("hello");//只会删除第一次出现的
System.out.println(list);
// list.remove(new Integer(9090980)); 认为9090980是索引
list.remove(new Integer(9090980));
System.out.println(list);
list.remove(0);//下标索引
System.out.println(list);
list.add("word");
System.out.println(list);
// 判断
System.out.println("hello在集合中是否存在:"+list.contains("hello"));
System.out.println("hello在集合中是否存在:"+list.contains("java"));
System.out.println(list);
System.out.println(list2);
System.out.println(list.contains(list2));
// 清空集合中所有的元素对象
// list.clear();
// System.out.println(list);
// 获取指定索引位置上的元素对象
System.out.println(list.get(1));
// 设置
// 下标1设置成"java"
list.set(1, "java");
System.out.println(list);
// 查找元素在集合中的位置,有的返回索引位置,没有的返回-1
System.out.println(list.indexOf("word")+"\t\t"+list.indexOf("list"));
// 遍历集合中元素的内容
System.out.println("---------普通for循环遍历--------");
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
System.out.println("---------增强for遍历----------");
for (Object object : list) {
System.out.println(object);
}
System.out.println("---------迭代器遍历-----------");
Iterator iter = list.iterator();//正向的遍历
while(iter.hasNext()){//判断集合中有没有元素
Object obj = iter.next();
System.out.println(obj);
}
System.out.println("使用listIterator()遍历");
ListIterator liter = list.listIterator();
System.out.println("----------正向-----------");
System.out.println("集合头后面还有元素吗?"+liter.hasNext());
System.out.println("集合头前面还有元素吗?"+liter.hasPrevious());
while(liter.hasNext()){
System.out.println(liter.next());
}
System.out.println("----------反向-----------");
System.out.println("集合头后面还有元素吗?"+liter.hasNext());
System.out.println("集合头前面还有元素吗?"+liter.hasPrevious());
while(liter.hasPrevious()){
System.out.println(liter.previous());
}
}
}
ArrayList_JDK源码分析一
1、构造方法
2、添加方法
3、扩容的原理
package cn.xjion.pro09;
import java.util.ArrayList;
public class TestArrayList2 {
/**ArrayList源码分析
*(1)无参构造方法
* this.elementData 是一个Object类型的数组
* DEFAULTCAPACITY_EMPTY_ELEMENTDATA;也是一个Object类型的数组
* DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};默认长度为0
* public ArrayList() {
* this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
* //相当于this.elementData={};
* }
*
*(2)带参构造方法
* public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
//this.elementData = new Object[20];
(3)添加方法 add(Object obj)
* public boolean add(E e) {
* //检测空间容量是否够用
ensureCapacityInternal(size + 1); // Increments modCount!!
//添加元素 elementData[size] = e;size++;
elementData[size++] = e;
return true;
}
(4)检测空间容量是否够用
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
首先调用执行,计算容量
calculateCapacity(elementData, minCapacity)
//calculateCapacity方法定义
* private static int calculateCapacity(Object[] elementData, int minCapacity) {
* //以下代码相当于elementData=={}
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
//Math.max(10,1);
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}//执行完之后的结果为10
//容量计算完毕后,执行ensureExplicitCapacity方法,ensureExplicitCapacity(10)
ensureExplicitCapacity方法定义
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
(5)扩充容量
private void grow(int minCapacity) { //10
// overflow-conscious code
int oldCapacity = elementData.length; //int oldCapacity=0;
int newCapacity = oldCapacity + (oldCapacity >> 1); //int newCapacity=0+(0>>1) 0
if (newCapacity - minCapacity < 0) //true;
newCapacity = minCapacity; //newCapacity = 10;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity); 数组拷贝 elementData的长度就是10
}
*/
public static void main(String[] args) {
ArrayList list = new ArrayList(20);
list.add("hello");
list.add("world");
list.add("hello");
list.add("world");
list.add("hello");
list.add("world");
list.add("hello");
list.add("world");
list.add("hello");
list.add("world");//第10个元素对象
/**当添加第11个元素时,所需容量为11,而数组的长度为10,已经无法容纳元素了,这个时候需要扩容
* 原始容量+原始容量>>1 得到新容量
* 10+10>>1 15
*/
list.add("hello");
}
}
ArrayList_JDK源码分析二
package cn.xjion.pro09;
import java.util.ArrayList;
import java.util.Iterator;
public class TestArrayList {
/**
* ArrayList源码分析_2
* (1)add(int index,Object obj)
* public void add(int index, E element) {
//源数组,源数组的开始位置,新数组,
System.arraycopy(elementData, index, elementData, index + 1,
size - index);//size-index,拷贝的元素的个数
elementData[index] = element; //将元素添加到索引为index的位置上
size++; //元素的个数+1
}
* @param args
*
* (2)get(int index)根据索引获取元素对象
* public E get(int index) {
return elementData(index); //调用了elementData()方法
}
//elementData方法的定义
* E elementData(int index) {
return (E) elementData[index]; //在Object类型的数组中根据索引取出元素对象
}
*
* (3)size()
* public int size() {
return size; //用于记录集合中元素的个数
}
(4)isEmpty()
public boolean isEmpty() {
return size == 0; //集合中一个元素都没有的时候,集合就是空的
}
(5)set(int index.Object obj)
public E set(int index, E element) {
E oldValue = elementData(index); //根据索引在数组中获取元素
elementData[index] = element; //将新元素设置到数组中索引为index的位置上
return oldValue; //返回原始元素对象
}
(6)remove(int index)
public E remove(int index) {
E oldValue = elementData(index); //根据索引获取原始元素对象
int numMoved = size - index - 1; //拷贝的元素的个数
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // 将最后一个位置设置为null
return oldValue; //返回原始元素对象
}
(7)clear()
public void clear() {
// clear to let GC do its work
for (int i = 0; i < size; i++)
elementData[i] = null;
size = 0;
}
(8)iterator()
*/
public static void main(String[] args) {
//创建ArrayList集合对象
ArrayList list = new ArrayList();
list.add("hello");
list.add("world");
list.add(0,"java");
System.out.println(list);
System.out.println(list.get(1));
System.out.println(list.size());
System.out.println(list.isEmpty());
System.out.println(list.set(2, "sql"));
System.out.println(list);
list.remove(1);
list.clear();
Iterator ite = list.iterator();
while(ite.hasNext()) {
Object obj = ite.next();
System.out.println(obj);
}
}
}
LinkedList 的特点_链表_JDK 源码分析
package cn.xjion.pro09;
import java.util.LinkedList;
public class TestLinkedList {
/**
* LinkedList底层数据结构是链表,删除和添加元素的效率比较高,数据结构复杂
* ArrayList底层数据结构是数组,删除和添加元素效率比较低
* @param args
*/
public static void main(String[] args) {
LinkedList list = new LinkedList();
//添加元素
list.add("hello");
list.addFirst("java");
list.addLast("world");
//删头,删尾
list.removeFirst();
list.removeLast();
System.out.println(list);
//遍历
for(Object obj:list) {
System.out.println(obj);
}
}
}
Vector用法和ArrayList区别
package cn.xjion.pro09;
import java.util.Iterator;
import java.util.Vector;
public class TestVector {
/**
* Vector的JDK源码分析
* (1)构造方法
* public Vector() {
this(10);
}
public Vector(int initialCapacity) { //10
this(initialCapacity, 0); //10,0
}
public Vector(int initialCapacity, int capacityIncrement) {
this.elementData = new Object[initialCapacity]; //相当于this.elementData = new Object[10];
this.capacityIncrement = capacityIncrement; //this.capacityIncrement=0;
}
(2)调用add方法添加元素
public synchronized boolean add(E e) {
ensureCapacityHelper(elementCount + 1); //检测容量是否够用
elementData[elementCount++] = e; //添加元素,同时元素个数加1
return true;
}
* @param args
*/
public static void main(String[] args) {
//创建了集合对象
Vector vector = new Vector();
System.out.println(vector.capacity()+"\t集合中元素的个数:"+vector.size());
//添加
vector.add("hello");
vector.add(0, "world");
vector.addElement("java"); //添加元素
System.out.println(vector);
//删除
//vector.remove(1);
//vector.remove("java");
//vector.clear();
//vector.removeElement("java");
//获取元素的方法
System.out.println(vector.get(1));
System.out.println(vector);
System.out.println("加强for循环");
for (Object obj:vector) {
System.out.println(obj);
}
System.out.println("使用迭代器遍历集合:");
for(Iterator ite = vector.iterator();ite.hasNext();) {
System.out.println(ite.next());
}
}
}
区别
底层数据结构相同,都是Object类型的数组
Vector的add()方法是同步方法,ArrayList的add()方法是非同步方法 Vector扩容每次扩充1倍,ArrayList每次扩充0.5倍 Vector是在调用构造方法时,直接初始化容量为10,ArrayList是在第一次调用添加方法时,初始化容量为10 Vector的版本是JDK1.0,ArrayList,Jdk1.2版 Vector是线程同步的,安全性高,效率低 ArrayList是线程非同步的,安全性低,效率高