集合架构*
注明:根据韩顺平老师做的笔记
大致分为两类
单列集合
双列集合
package com.company.Collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class javasourcedemo1 {
public static void main(String[] args) {
Collection col = new ArrayList();
col.add(new book("三国演义1","罗贯中1",30.11));
col.add(new book("三国演义2","罗贯中2",30.12));
col.add(new book("三国演义3","罗贯中3",30.13));
System.out.println("col"+col);
}
}
class book{
private String name;
private String author;
private double price;
public book(String name,String author,double price){
this.name =name;
this.author = author;
this.price = price;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}package com.company.Collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class javasourcedemo1 {
public static void main(String[] args) {
Collection col = new ArrayList();
col.add(new book("三国演义1","罗贯中1",30.11));
col.add(new book("三国演义2","罗贯中2",30.12));
col.add(new book("三国演义3","罗贯中3",30.13));
Iterator iterator = col.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
System.out.println("col"+col);
}
}
class book{
private String name;
private String author;
private double price;
public book(String name,String author,double price){
this.name =name;
this.author = author;
this.price = price;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAuthor(String author) {
this.author = author;
}
public String getAuthor() {
return author;
}
public void setPrice(double price) {
this.price = price;
}
public double getPrice() {
return price;
}
@Override
public String toString() {
return "book{" +
"name='" + name + '\'' +
", author='" + author + '\'' +
", price=" + price +
'}';
}
public book(){}
}
public void setAuthor(String author) {
this.author = author;
}
public String getAuthor() {
return author;
}
public void setPrice(double price) {
this.price = price;
}
public double getPrice() {
return price;
}
@Override
public String toString() {
return "book{" +
"name='" + name + '\'' +
", author='" + author + '\'' +
", price=" + price +
'}';
}
public book(){}
}
Collection 接口遍历
方式一 使用iterator (迭代器)
2)
遍历的三个过程
1、下移
2、将下移以后的集合位置元素返回
3、当遍历结束后 iterator迭代器 游标指向最后的元素
4、如果希望再次遍历 需要重置我们的迭代器
idea快捷键生成while ==》 itit
查找生成快捷键 ctrl+j
方式二增强for循环
1、使用增强for 在collection集合中
2、增强for 底层仍然事迭代器
3、增强for可以理解成就是简化版的迭代器遍历
4、快捷键方式
方式三使用普通的for
for (int i = 0;i<list.size();i++){
System.out.println("list="+list.get(i));
}
//java测试
package com.company.Collection;
import com.company.Collection.javasourcedemo1;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class dogfor {
public static void main(String[] args) {
Collection list= new ArrayList();
list.add(new dog("张",20));
list.add(new dog("佳",20));
list.add(new dog("琦",20));
Iterator iterator = list.iterator();
//使用for增强
for (Object dog:list){
System.out.println("dog:"+dog);
}
while (iterator.hasNext()) {
System.out.println("iterator:"+iterator.next());
}
}
}
class dog{
private String name;
private int 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;
}
public dog(String name,int age){
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "dog{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
一、list(Vector|Arraylist |Linkedlist)
1、list接口和常用方法
List接口基本介绍
list接口时Collection接口的子接口 list.java
1)list集合接口中元素有序就是添加顺序和取出顺序一致 可重复
2)list集合中每个元素都有其对应的顺应索引 支持其索引
3)list容器中元素都对应一个整数型的序号记载其在容器中的位置 可以根据序号存取容器中的元素
4)jdk API 中实现的list接口实现类有:
Vector|Arraylist |Linkedlist
1.1、存取顺序一致可重复
package com.company.Collection;
import java.util.ArrayList;
import java.util.List;
public class listdemo1 {
public static void main(String[] args) {
//1)list集合接口中元素有序就是添加顺序和取出顺序一致 可重复
List list = new ArrayList<>();
list.add("张");
list.add("佳");
list.add("琦");
list.add("孙");
list.add("张");
list.add("佳");
list.add("琦");
list.add("孙");
System.out.println("list="+list);
}
}
1.2支持其索引
//list集合中每个元素都有其对应的顺应索引 支持其索引
System.out.println(list.get(3));
1.3数型的序号记载其在容器中的位置 可以根据序号存取容器中的元
//list集合中每个元素都有其对应的顺应索引 支持其索引
System.out.println(list.get(3));
1.4list接口的常用方法
1、void add(int index,Object ele) 在index位置插入ele元素
在索引为一的位置插入一个字符串对象
2、boolean addAll(int index, Collection eles):从index位置将eles中所有元素添加进来
3、Object get(int index) :获取指定的index位置元素
4、int indexOf(Object obj):返回obj在集合中首次出现的位置,当所搜内容不存在时 就会返回-1
5、int lastIndexOf(Object obj):返回obj在集合中末次出现的位置,当所搜内容不存在时 就会返回-1
6、object remove(int index):移除指定index 位置的元素 并返回此元素
7、Object set(int index, Object ele):设置指定index位置的元素ele,相当于替换
index 索引是必须要存在的 放在最后一个没有也是不可以 必须得存在位置
8、List subList(int fromIndex, int toIndex):返回从fromIndex 到toIndex位置的子集合
//[0,2) 左闭右开集合
public class ListMethod_ {
public static void main(String[] args) {
List list = new ArrayList();
list.add("宝宝");
list.add("憨批");
//1、void add(int index,Object ele) 在index位置插入ele元素
//在索引为一的位置插入一个字符串对象
list.add(1,"zjq");
System.out.println("list="+list);
//2、boolean addAll(int index, Collection eles):从index位置将eles中所有元素添加进来
List listappend = new ArrayList();
listappend.add("宝儿");
listappend.add("猪");
list.addAll(1,listappend);
System.out.println("list="+list);
//3、Object get(int index) :获取指定的index位置元素
//说过
//4、int indexOf(Object obj):返回obj在集合中首次出现的位置,当所搜内容不存在时 就会返回-1
System.out.println(list.indexOf("猪"));
//5、int lastIndexOf(Object obj):返回obj在集合中末次出现的位置,当所搜内容不存在时 就会返回-1
list.addAll(list);
System.out.println(list.lastIndexOf("zjq"));
//6、object remove(int index):移除指定index 位置的元素 并返回此元素、
System.out.println(list);
list.remove(3);
System.out.println(list);
//7、Object set(int index, Object ele):设置指定index位置的元素ele,相当于替换
//index 索引是必须要存在的 放在最后一个没有也是不可以 必须得存在位置
list.set(1,"张佳琦");
System.out.println(list);
//8、List subList(int fromIndex, int toIndex):返回从fromIndex 到toIndex位置的子集合
//[0,2) 左闭右开集合
List list1 = list.subList(0,2);
System.out.println(list1);
}
}
二、ArrayList底层结构和源码分析
ArrayListDetail.java
1)permits all elements,including null,ArrayList 可以加入null 并且多个
public static void main(String[] args) {
ArrayList arrayList = new ArrayList();
int[] arr = {2,4,5,6,10};
arrayList.add(null);
arrayList.add("jack");
arrayList.add(null);
for (int o:arr) {
System.out.println(o);
}
System.out.println(arrayList);
}
2)ArrayList 是由数组来实现数据存储的
3)ArrayList 基本等同与Vector 除了ArrayList是线程不安全(执行效率高)在多线程的条件下不使用arrayList
ArrayList原因没有synchronized
public boolean add(E e) {
++this.modCount;
this.add(e, this.elementData, this.size);
return true;
}
private void add(E e, Object[] elementData, int s) {
if (s == elementData.length) {
elementData = this.grow();
}
elementData[s] = e;
this.size = s + 1;
}
public void ensureCapacity(int minCapacity) {
if (minCapacity > this.elementData.length && (this.elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA || minCapacity > 10)) {
++this.modCount;
this.grow(minCapacity);
}
}
Vector原因有synchronized就安全互斥
public synchronized boolean add(E e) {
++this.modCount;
this.add(e, this.elementData, this.elementCount);
return true;
}
ArrayList源码
transient瞬间,短暂的不会被序列化
capacity 是容量意思
explicit是否要移动
>> 右移 就是相当于除以2
debug时的数据都是阉割过的数据如果在debug中完全显示 将enavle alternative view for Collections classes 勾选给划掉
E是泛型类,可传入的是你要传入的参数类型 E e是泛型标识符
1)ArrayList 中维护一个Object类型的数组(elementData)[debug 看源码]
transient Object[] elementData;
2)当创建ArrayList 对象时 如果使用的时无参则初始的elementData容量为0,第一此添加 则扩容elementData 为10 如果再次扩容发 则扩容elementData1.5倍
无参构造 第一次 0——10 ——>15——15+15/2 ==22 ——>33…
3)如果使用的时指定大小的构造器 则初始elementData容量为指定的大小,如果需要扩容 直接扩容elementData的1.5倍
无参构造扩容过程
有参构造扩容过程
三、Vector底层结构和源码剖析
Vector的基本介绍
1)vector类定义说明
2)Vector底层也是对象数组 protect Object[] elementData;
3)Vector 线程同步安全 ,vector类的操作方法带有synchronzed
底层结构 | 版本 | 线程安全效率 | 扩容倍数 | ||
---|---|---|---|---|---|
ArrayList | 可变数组 | jdk1.2 | 不安全效率高 | 无参:第一次10 从第二次1.5倍扩 有参1.5倍扩 | |
Vector | 可变数组Object[] | jdk1.0 | 安全效率不高 | 如果无参 默认10 满后按照2倍扩 如果是指定大小 则每次直接按2倍扩 |
四、linkedList底层结构
4.1 LinkedList全面说明
1)LinkedList底层实现了双向链表和双端队列特点
2)可以添加任意元素 元素可以重复 包括null
3)线程不安全,没有实现同步、
4.2 LinkedList的底层操作机制
1)LinkedList底层维护了一个双向链表
2)LinkedList中维护了两个属性first和last分别指向首节点 和尾节点
3)每个节点(node 对象)里面维护了prev、next、item三个属性 其中通过prev指向前一个通过next指向后一个最终实现双向链表
4)所以LinkedList的元素添加和删除不是通过数组完成的 相对来说效率高
5)模拟一个简单的双向链表
4.3增删查改案例
package com.company.Collection.list;
import java.util.LinkedList;
public class LinkedList_ {
public static void main(String[] args) {
LinkedList linkedList = new LinkedList();
for (int i = 0; i < 2; i++) {
linkedList.add(i);
}
linkedList.add(100);
linkedList.add(100);
for (Object object:linkedList) {
System.out.println(object);
}
linkedList.set(0,"zjq");
System.out.println("========");
for (Object object:linkedList) {
System.out.println(object);
}
Object object = linkedList.get(0);
System.out.println("object="+object);
System.out.println("first="+linkedList.getFirst());
System.out.println("last="+linkedList.getLast());
}
}
4.4源码解析
1、第一步
LinkedList linkedList = new LinkedList();
2、这是 linklist属性 first null,lastnull
3、执行 添加
public boolean add(E e) {
linkLast(e);
return true;
}
3.1、添加到双向链表的最后的
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++;
}
4、删除
4.1第一步
linkedList.removeFirst(1);
public E removeFirst() {
final Node<E> f = first;
if (f == null)
throw new NoSuchElementException();
return unlinkFirst(f);
}
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;
}
二、最后总结选择结构使用哪个比较好
底层结构 | 增删效率 | 改查效率 | |
---|---|---|---|
ArrayList | 可变数组 | 较低、数组扩容 | 较高 |
LinkedList | 双向链表 | 较高,通过链表追加 | 较低 |
st(f);
}
```java
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;
}
二、最后总结选择结构使用哪个比较好
底层结构 | 增删效率 | 改查效率 | |
---|---|---|---|
ArrayList | 可变数组 | 较低、数组扩容 | 较高 |
LinkedList | 双向链表 | 较高,通过链表追加 | 较低 |