1.集合框架
1.1 概念
Java集合框架(Java Collections Framework简称JCF)是为表示和操作集合,而规定的一种统一的标准的体系结构。集合框架包含三大块内容:对外的接口、接口的实现和对集合运算的算法。
集合就是用于存储对象的容器。 只要是对象类型就可以存进集合框架中。集合的长度是可变的。 集合中不可以存储基本数据类型的值
1.2 集合和数组的区别
数组和集合相比,数组的缺点是它长度是固定的,没有办法动态扩展。而集合存储数据时是没有长度限制的,是可以动态扩展的。集合容器因为内部的数据结构不同,有多种不同的容器对象。这些容器对象不断的向上抽取,就形成了集合框架。
2.为什么使用集合?
1)我们原来讲过数组.思考: 数组有缺陷?--定容【一定数组定义好,他们得长度就无法改变.如果需要改变数组得长度,变得很复杂。
2)我们是否可以定义一个长度改变的容器。---当然可以。
3)手撕可变长度的容器
package com.java0415.test;
import java.util.Arrays;
/**
* @author: jh
* @create: 2022/4/15
*/
public class MyArray {
private Object [] arr; //声明一个Object类型的数组
private int size;//表示数组的下标
public MyArray(){ //无参构造函数
this(3);
}
public MyArray(int initSize){ //有参构造函数
if(initSize<0){ //长度不合法
throw new RuntimeException("sorry 数组的长度有误。");
}
arr=new Object[initSize];
}
//把元素o放入数组arr
public void addData(Object o){
//判断你的数组是否已满
if(size>=arr.length){
//扩容--(1)容器的长度变长 (2)把原来容器中的元素复制到新的容器中
Object[] newArr = Arrays.copyOf(arr, size * 2);
arr=newArr;
}
arr[size]=o;
size++;
}
//根据下标获取数组中的元素。
public Object getData(int index){
if(index>=size){
throw new ArrayIndexOutOfBoundsException("下标越界");
}
Object o = arr[index];
return o;
}
}
我们自己可以手写一个可变的容器,那么别人也可以手写可变的容器。
java官网 基于数组 根据不同的数据结构 创建了多个类 而这些类统称 为集合框架。
以后 我们在说集合框架时 就表示多个类。
3.集合的架构
4.List集合
4.1 ArrayList
package com.java0415.test;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* @author: jh
* @create: 2022/4/15
*/
public class Demo1 {
public static void main(String[] args) {
//创建集合对象
List list = new ArrayList();
//添加操作
list.add("java01");
list.add("java02");
list.add(15.5);
list.add(18);
list.add(true);
list.add(new Date());
System.out.println(list);
list.add(2,"hello");
System.out.println(list);
List list2=new ArrayList();
list2.add("a");
list2.add("b");
list.addAll(list2);
System.out.println(list);
//删除操作
list.remove(2);
System.out.println(list);
//list.clear();
System.out.println(list);
//修改操作
list.set(1,"张三");
System.out.println(list);
//查询操作
Object o = list.get(3);
System.out.println(o);
int size = list.size();
System.out.println(size);
boolean f = list.contains("java03");
System.out.println(f);
int index = list.indexOf("张三");
System.out.println(index);
for(int i=0;i<list.size();i++){
Object o1 = list.get(i);
System.out.println(o1);
}
}
}
ArrayList底层源码
从构造方法来入手。new ArrayList(22) 底层声明了一个Object类型的数组 名字elementData
Object[] elementData
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) { //大于0
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) { //等于初始化为一个空数组
this.elementData = EMPTY_ELEMENTDATA;
} else { //抛出一个异常
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
==========add("java01")======E理解为Object类型================
public boolean add(E e) {
ensureCapacityInternal(size + 1); // 扩容
elementData[size++] = e; //把元素赋值给数组的相应位置
return true;
}
==========indexOf("java02") 判断元素在集合中第一次的位置=============
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i])) //和数组中的每个元素内容进行比对
return i; //返回元素在集合中位置
}
return -1;
}
===========size() 请求数组的长度======================
public int size() {
return size;
}
============contain("java05")判断元素是否在集合中==============
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
===============get(1) 获取指定位置的元素========
public E get(int index) {
rangeCheck(index); //判断指定的位置是否合法
return elementData(index);
}
E elementData(int index) {
return (E) elementData[index];
}
============toString() 为什么不打印对象的引用地址
[java01, java02, java03, java02]因为重写了Object里面的toString方法。
public String toString() {
Iterator<E> it = iterator();
if (! it.hasNext())
return "[]";
StringBuilder sb = new StringBuilder();
sb.append('[');
for (;;) {
E e = it.next();
sb.append(e == this ? "(this Collection)" : e);
if (! it.hasNext())
return sb.append(']').toString();
sb.append(',').append(' ');
}
}
通过对ArrayList方法的底层代码分析:底层就是对数组的操作。
ArrayList的底层就是基于数组实现的。
4.2 LinkedList
链表结构
package com.java0415.test.test1;
import java.util.LinkedList;
/**
* @author: jh
* @create: 2022/4/15 22:06
*/
public class DemoLinkedList {
public static void main(String[] args) {
LinkedList linkedList = new LinkedList();
//添加操作
linkedList.add("张三");
linkedList.addFirst("李四");
linkedList.addLast("王五");
linkedList.addFirst("徐六");
linkedList.addLast("郭七");
System.out.println(linkedList);
//删除操作
linkedList.removeFirst();
System.out.println(linkedList);
linkedList.remove(2);
System.out.println(linkedList);
//linkedList.removeLast();
//System.out.println(linkedList);
//修改操作
linkedList.set(1,"java11");
System.out.println(linkedList);
//查询操作
int size = linkedList.size();
boolean empty = linkedList.isEmpty();
boolean b = linkedList.contains("java01");
Object o = linkedList.get(1);
Object first = linkedList.getFirst();
System.out.println(first);
Object last = linkedList.getLast();
System.out.println(last);
}
}