1. 集合框架
单列集合(单个对象)

双列集合(键值对)

2.Collection接口和常用方法
实现子类ArrayList
List list = new ArrayList();
2.1 add
list.add(); //可存入任何类型的对象,直接存入数据或者布尔值会进行类型判别
list.add(10); //相当于list.add(new Integer(10))
2.2 remove
list.remove()//
list.remove(index); //指定元素下标删除
list.remove("object"); //指定对象删除
Q:怎么以删除指定对象方式删除整型元素?
2.3 contains()
//接受一个对象,查找元素是否存在,返回boolean
2.4 size()
//获取元素个数
2.5 isEmpty()
//判断是否为空
2.6 clear()
//清空
2.7 addAll()
//接受一个实现Colleticon的对象并将其加入当前对象
//合并两个ArrayList
3.Collection接口遍历元素方式
迭代器Iterator执行原理
//hasNext()判断是否有下一个元素
//next()将指针下移并返回下移后位置的元素
//System.out.println(iterator.next())
3.1 使用Collection实现的接口iterator遍历--while
Collection list = new ArrayList();
while(list.hasNext()) {
Object obj = iterator.next();
System.out.println(obj);
}
循环结束后,指针指向列表的最后一个元素
若要重新循环遍历,则要重置iterator
iterator = list.iterator();
//重置iterator,
3.2 使用Collection接口遍历对象--for循环增强
Collection list = new ArrayList();
list.add(new Book("Alan", 12));
list.add(new Book("Hulk", 21));
Iterator iterator = list.iterator();
for(Object book : list) {
//book为循环对象
System.out.println("book=" + Book);
}
//也可以用来访问数组
int[] nums = {1,2,3};
for(Object i : nums){
System.out.println(i);
}
底层仍然是迭代器
for循环的判断语句中,先调用Iterator
public Iterator<E> iterator() {
return new Itr();
}
接着判断是否有下一个元素
public boolean hasNext() {
return cursor != size;
}
最后调用next()方法
public E next() {
checkForComodification();
int i = cursor;
}
4. 编译类型和运行类型
编译时类型由声明该变量时使用的类型决定(比如可声明为类的父类),运行时类型由实际赋给该变量的对象决定
(参考C++的动态绑定)
与方法不同的是,对象的属性则不具备多态性。通过引用变量来访问其包含的实例属性时,系统总是试图访问它编译时类所定义的属性,而不是它运行时所定义的属性。
5. List接口和常用方法
5.1 List接口特点:
5.1.1 List集合类中元素有序(添加顺序和取出顺序一致),且可重复
5.1.2 支持顺序索引(索引从0开始)
5.1.3 实现List接口的类有ArrayList,LinkedList,Vector,Stack,AbstractList等
5.2 List接口方法:
List list = new ArrayList();
List list_2 = new ArrayList();
list_2.add("four");
list_2.add("five");
list.add("one");
list.add("three");
list.add(1,"two");
list.add("one");
//insert new object into the index you want
list.addAll(1,list_2);
//insert another Collection Object into the index you want
System.out.println(list.get(1));
//get object by index
System.out.println(list.indexOf("one"));
//return the index where the object is setted first time
System.out.println(list.lastIndexOf("one"));
//return the index where the object is setted last time
System.out.println(list.remove(1));
//remove object by index and return the object
System.out.println(list);
list.set(1, "ten");
//replace the object by index with a new object
System.out.println(list.subList(1,4));
//get the subList by index
//from fromIndex to toIndex(not involve toIndex)
6.List接口的三种实现类ArrayList,Vector,LinkedList的三种遍历方式
System.out.println("\n--------in while-------\n");
Iterator it = list.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
System.out.println("\n---------in for--------\n");
for(Object o : list) {
System.out.println(o);
}
System.out.println("\n-------in simple--------\n");
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
//编译类型为List,运行类型ArrayList,Vector,LinkedList都适用
7. ArrayList
7.1 可以加入多个null
List list = new ArrayList();
list.add(null);
7.2 ArrayList是由数组来实现数据存储的
7.3 ArrayList基本等同于Vector,执行效率高,但是是线程不安全的。添加元素时没有synchronized互斥操作。
7.4 ArrayList底层机制和源码分析
ArrayList构造器:

7.4.1 ArrayList中维护了一个Object类型的数组elementData(什么类型的数据都可以放)
transient Object[] elementData; //transient 表示该属性不会被序列化(序列化详见JAVA--序列化)
反序列化:从IO流中恢复对象
7.4.2 创建ArrayList对象时,如果使用的是无参构造器,则初始elementData容量为0,第一次添加,则扩容elementData为10,如需要再次扩容,则扩容elementData为1.5倍
7.4.3 如果使用的是指定大小的构造器,则初始化elementData容量为指定大小,如果需要扩容,则直接扩容为elementData为1.5倍
Debug : ArrayList扩容
ArrayList list = new ArrayList();
for(int i = 1; i <= 10; i++) {
list.add(i); //jump
}
public boolean add(E e) {
ensureCapacityInternal(size + 1);
//size = 0
//jump
elementData[size++] = e;
//size是位置指针
return true;
}
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); //minCapacity=1
//第一次扩容时候,DEFAULT_CAPACITY=10,minCapacity=1
}
ensureExplicitCapacity(minCapacity);
//这里minCapacity = 10
//jump
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;//扩容计数
if (minCapacity - elementData.length > 0)
grow(minCapacity);
//jump
}
Tips:
transient Object[] elementData;
// java 的transient关键字为我们提供了便利,你只需要实现Serilizable接口,将不需要序列化的属性前添加关键字transient,序列化对象的时候,这个属性就不会序列化到指定的目的地中。
private void grow(int minCapacity) {
int oldCapacity = elementData.length;
//初始elementData.length = 0
int newCapacity = oldCapacity + (oldCapacity >> 1);
// ">>"位移操作符,变为之前的二分之一,即新的容量为之前的1.5倍
if (newCapacity -minCapacity < 0)
newCapacity = minCapacity;
//如果扩容后的容量仍然小于所需容量,则新容量之间等于所需容量
if(newCapacity - Max_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
//如果扩容后的容量大于ARRAY提供的最大容量,则
elementData = Arrays.cptyOf(elementData, newCapacity);
//将数据移入扩容后的ArrayList
//junp
//拷贝之前的数据,并把没有值的位置置为null
}
7.4.4 如果使用的是指定大小的构造器,则初始elementData容量为指定大小,如果需要扩容,则直接扩容elementData为1.5倍
ArrayList list = new ArrayList(6);
for (int i = 1; i <= 10; i++) {
list.add(i);
}
//当循环至i=7时,list扩容为9
本文详细介绍了Java集合框架中的单列集合(单对象)和双列集合(键值对),重点讲解了ArrayList、Vector(Vector是ArrayList的线程安全版本)和LinkedList的区别。涵盖了添加、删除、遍历、编译与运行类型等内容,以及ArrayList的内部实现机制。
1103

被折叠的 条评论
为什么被折叠?



