数组可变大小:大概是把数组复制进新数组,扩展
List list = new ArrayList();
list.add("abc1");
list.add("abc2");
list.add("abc3");
// list.add(1,"abc9");
// System.out.println(list); //[abc1, abc9, abc2, abc3]
// System.out.println(list.remove(2)); //abc3
// System.out.println(list.set(1,"abc8")); //abc2
// System.out.println(list.get(1)); //abc2
// System.out.println(list.subList(1,2)); //[abc2]
// Iterator it = list.iterator();
// while (it.hasNext()){
// System.out.println(it.next());
// }
// //list特有取值方式
// for(int i=0;i<list.size();i++){
// System.out.println(list.get(i));
// }
ListIterator
// Iterator it = list.iterator();
// while (it.hasNext()){
// Object obj = it.next();
// //java.util.ConcurrentModificationException
// //在迭代过程中不要使用集合操作元素,容易出现异常
// //可以使用Iterator的子接口ListIterator来完成迭代中对元素的操作
// if(obj.equals("abc2")){
// list.add("abc9");
// }else{
// System.out.println(obj);
// }
// }
// System.out.println(list);
ListIterator it = list.listIterator();
while (it.hasNext()){
Object obj = it.next();
if(obj.equals("abc2")){
it.set("abc9");
}
}
System.out.println(list); //[abc1, abc9, abc3]
LinkedList源码分析
LinkedList list = new LinkedList();
list.add("java");
/*
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
*/
list.addFirst("hello");
/*
private void linkFirst(E e) {
final Node<E> f = first;
final Node<E> newNode = new Node<>(null, e, f);
first = newNode;
if (f == null)
last = newNode;
else
f.prev = newNode;
size++;
modCount++;
}
*/
list.addLast("world");
/*
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
*/
list.removeLast();
/*
private E unlinkLast(Node<E> l) {
// assert l == last && l != null;
final E element = l.item;
final Node<E> prev = l.prev;
l.item = null;
l.prev = null; // help GC
last = prev;
if (prev == null)
first = null;
else
prev.next = null;
size--;
modCount++;
return element;
}
*/
list.removeFirst();
/*
private E unlinkFirst(Node<E> f) {
// assert f == first && f != null;
final E element = f.item;
final Node<E> next = f.next;
f.item = null;
f.next = null; // help GC
first = next;
if (next == null)
last = null;
else
next.prev = null;
size--;
modCount++;
return element;
}
*/
System.out.println(list);
LinkedList link = new LinkedList();
link.addFirst("abc1");
link.addFirst("abc2");
link.addFirst("abc3");
// System.out.println(link.getFirst()); //abc3
// System.out.println(link.removeFirst()); //abc3
// Iterator it = link.iterator();
// while(it.hasNext()) {
// System.out.println(it.next()); //abc3 abc2 abc1
// }
/*
* LinkedList模拟队列和堆栈
*/
public class LinkedListSQ {
private LinkedList link;
private String type;
public LinkedListSQ() {
this.link = new LinkedList();
}
public void setType(String type) {
this.type = type;
}
public void myAdd(Object obj) {
this.link.addLast(obj);
}
public Object myPop() {
if(this.type == "stack") {
return this.link.removeLast();
}else {
return this.link.removeFirst();
}
}
public boolean isNull() {
return this.link.isEmpty();
}
}
//main
LinkedListSQ sq = new LinkedListSQ();
sq.myAdd("abc1");
sq.myAdd("abc2");
sq.myAdd("abc3");
//sq.setType("stack");
while(!sq.isNull()) {
System.out.println(sq.myPop()); //abc1 abc2 abc3 abc3 abc2 abc1
}
LinkedList底层是双向链表
从结构上,我们还看到了LinkedList实现了Deque接口,因此,我们可以操作LinkedList像操作队列和栈一样~
add
remove
get
ArrayList所有方法
List list = new ArrayList();
//add
list.add("hello");
list.add("world");
//AbstractCollection中定义了toString直接输出数组格式
System.out.println(list); //[hello, world]
//size
System.out.println(list.size()); //2
//empty
System.out.println(list.isEmpty()); //false
//add addAll
List list2 = new ArrayList();
list2.add("hello");
list2.add(123); //自动装箱
list.addAll(list2);
System.out.println(list); //[hello, world, hello, 123]
//remove removeAll
list.remove("hello");
System.out.println(list); //[world, hello, 123]
//list.remove(123); //java.lang.IndexOutOfBoundsException
list.remove(new Integer(123));
System.out.println(list); //[world, hello]
list.remove(0);
System.out.println(list); //[hello]
System.out.println(list2); //[hello, 123]
list.add("world");
list.add(123);
list.removeAll(list2); //删除交集
System.out.println(list);
//retainAll
list.add("hello");
list.add(123);
System.out.println(list);
list.retainAll(list2); //交集
System.out.println(list2);
System.out.println(list); //[hello, 123]
//contains containsAll
list.add("world");
System.out.println(list.contains(123)); //true
System.out.println(list.containsAll(list2)); //true
//clear
list2.clear();
System.out.println(list2); //[]
//get
System.out.println(list); //[hello, 123, world]
System.out.println(list.get(0)); //hello
//set
list.set(1, 456);
System.out.println(list); //[hello, 456, world]
//add
list.add(1,true);
System.out.println(list); //[hello, true, 456, world]
//indexOf
System.out.println(list.indexOf(true)); //1
//foreach
for (Object object : list) {
System.out.println(object);
}
//for
for(int i=0;i<list.size();i++) {
System.out.println(list.get(i));
}
//iterator
Iterator iterator = list.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
//listIterator
ListIterator iterator2 = list.listIterator();
while(iterator2.hasNext()) {
System.out.println(iterator2.next());
}
while(iterator2.hasPrevious()) {
System.out.println(iterator2.previous());
}
注意自定义对象在遍历的时候需要向下转型
ArrayList al = new ArrayList();
al.add(new Person("list1",21)); //向上转型为了Object
al.add(new Person("list2",22));
al.add(new Person("list3",23));
Iterator it = al.iterator();
while(it.hasNext()) {
Person p = (Person)it.next();
System.out.println(p.getName()+"--"+p.getAge());
}
//Person
public class Person {
private String name;
private int age;
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
ArrayList去重
//main
ArrayList al = new ArrayList();
al.add(new Person("list1",21));
al.add(new Person("list2",22));
al.add(new Person("list3",23));
al.add(new Person("list4",24));
al.add(new Person("list1",21));
System.out.println(al);
al = getSingleArrayList(al);
System.out.println(al);
private static ArrayList getSingleArrayList(ArrayList al) {
ArrayList temp = new ArrayList();
Iterator it = al.iterator();
while(it.hasNext()) {
Object obj = it.next();
//contains和remove都是使用的equals方法来比较筛选,所以可以操作equals来控制
//ArrayList不关系到hashCode
if(!temp.contains(obj)) {
temp.add(obj);
}
}
return temp;
}
//Person
public class Person extends Object {
private String name;
private int age;
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//覆盖hashCode和equals方法
@Override
public boolean equals(Object obj) {
if(this == obj) {
return true;
}
if(!(obj instanceof Person)) {
throw new ClassCastException("类型错误!");
}
System.out.println(this+"..equals.."+obj);
Person p = (Person)obj;
return this.name.equals(p.name) && this.age == p.age;
}
@Override
public int hashCode() {
System.out.println(name+"|"+age+"...hashCode=" + (name.hashCode()+age*35));
return name.hashCode()+age*35;
}
}
ArrayCopy
int[] arr = {1,2,3,4,5,6};
System.arraycopy(arr, 3, arr, 2, 3); //arr位置为3的元素开始复制3个,替换arr位置为2开始的3个元素
System.out.println(Arrays.toString(arr));
ArrayList源码分析-扩容
public class TestArrayList {
/**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) { //true
//Math.max(10,1);
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity; //执行完之后的结果为 10
}
//容量计算完毕后,执行ensureExplicitCapacity方法 ensureExplicitCapacity(10)
ensureExplicitCapacity方法定义
private void ensureExplicitCapacity(int minCapacity) { //10
modCount++;
// overflow-conscious code
* 10-0 >0 true
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
(5)扩充容量
private void grow(int minCapacity) { //10
// overflow-conscious code
int oldCapacity = elementData.length; //int oldCapactiy=0;
int newCapacity = oldCapacity + (oldCapacity >> 1); //int newCapacity=0+0>>1 结果为0
if (newCapacity - minCapacity < 0) // 0-10<0 true
newCapacity = minCapacity; //newCapacity=10;
elementData = Arrays.copyOf(elementData, newCapacity); //数组拷贝 elementData的长度就是 10
}
* */
public static void main(String[] args) {
ArrayList list=new ArrayList();
//第一次调用添加方法时,完成Object类型数组的初始化容量 ,10
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");//当添加第11个元素对象时 怎么办?
Object [] obj={};
}
}
ArrayList源码分析-操作
package com.bjsxt.arraylist.source;
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
}
(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");//在索引为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);
}
}
}
属性:
根据上面我们可以清晰的发现:ArrayList底层其实就是一个数组,ArrayList中有扩容这么一个概念,正因为它扩容,所以它能够实现“动态”增长
add(int index, E element)
get方法
细节说明
ArrayList:
LinkedList:
Vector:
总的来说:查询多用ArrayList,增删多用LinkedList。
ArrayList增删慢不是绝对的(在数量大的情况下,已测试):
如果增加元素一直是使用add()(增加到末尾)的话,那是ArrayList要快
一直删除末尾的元素也是ArrayList要快【不用复制移动位置】
至于如果删除的是中间的位置的话,还是ArrayList要快!.
源码分析
package com.bjsxt.vector;
import java.util.ArrayList;
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;
}
* */
public static void main(String[] args) {
//创建了集合对象
Vector vector=new Vector();
System.out.println(vector.capacity()+"\t集合中元素的个数:"+vector.size());
//ArrayList al=new ArrayList();
//al.add("hello");
//添加
vector.add("hello");
vector.add(0, "world");
vector.addElement("java"); //添加元素
vector.add("hello");
vector.add(0, "world");
vector.add("hello");
vector.add(0, "world");
vector.add("hello");
vector.add(0, "world");
vector.add(0, "world");
vector.add("hello");//添加第十一个元素
System.out.println(vector.capacity()+"\t集合中元素的个数:"+vector.size());
System.out.println("集合中元素的个数:"+vector.size());
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());
}
Iterator ite=vector.iterator();
while(ite.hasNext()){
System.out.println(ite.next());
}
}
}
ListIterator可以在迭代时添加元素
public class TestIterator {
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<String>();
arrayList.add("java");
arrayList.add("hello");
arrayList.add("world");
//Iterator<String> ite = arrayList.iterator();
/*
* private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
Itr() {}
public boolean hasNext() {
return cursor != size;
}
@SuppressWarnings("unchecked")
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
}
* */
// while(ite.hasNext()) {
//// if(ite.next().equals("hello")) {
//// arrayList.add("sql"); //java.util.NoSuchElementException
//// }
// System.out.println(ite.next());
// }
ListIterator<String> it = arrayList.listIterator();
while(it.hasNext()) {
String string = it.next();
if("hello".equals(string))
it.add("sql");
}
System.out.println(arrayList);
}
}