1.1目录
1.为什么使用集合?
2.集合架构有哪些?
3.List集合
4.ArrayList集合
5.LinkedLIst集合
6.Set集合
7.HashSet集合
8.TreeSet集合
9.Map
10.HashMap集合
11.TreeMap集合
1.2为什么使用集合
数组有缺陷长度固定(一旦数组定义好,数组的长度就无法改变)没有办法动态扩展 如果需要改变数组长度,变的很复杂 而集合(集合就是用于存储对象的容器)存储数据时是没有长度限制的,是可以动态扩展的。
是否可以自己定义长度可变的容器--当然可以
手撕一个长度可变的容器
//自定义一个自动扩容的容器 public class MyArray3 { //声明定义一个Object类型数组 private Object[] arr; //声明一个变量充当数组的下标 private int size; //创建一个无参构造 public MyArray3() { } //创建一个有参构造 public MyArray3(int initSize) { //判断传过来的参数是否有误 if (initSize<0){ throw new RuntimeException("数组长度有误"); } //将传过来的参数赋值给定义的数组 创建一个定容数组 arr=new Object[initSize]; } //创建一个存储元素的方法 public void addData(Object o){ //判断下标是否超过定容数组的长度 if (size>=arr.length){ //数组满了就要扩容 1容器的长度变大变长 2把原来容器的元素复制到新的容器中去 //Arrays(数组的工具类) original(起初的 原先的) 将原来的元素扩容到新的地方 Object[] al = Arrays.copyOf(arr, arr.length * 2); } //将传递过来的元素存储到数组中来 不能直接传到0的位置这样数值覆盖 就不能创建一个动态扩容的数组了 //需要声明一个变量初始值为0 然后让其自增 arr[size]=o; size++; } //创建一个根据传过来的下标 查找元素 public Object getData(int index){ //判断下标是否越界 if (index>=size){ throw new ArrayIndexOutOfBoundsException("下标越界异常"); } //入过传过来的下标没有越界异常根据这个下标查到元素并返回 Object o = arr[index]; return o; } @Override public String toString() { return "MyArray3{" + "arr=" + Arrays.toString(arr) + ", size=" + size + '}'; } }
测试类
public class TestMyArray3 { public static void main(String[] args) { MyArray3 myArray3 = new MyArray3(2); myArray3.addData("张三"); myArray3.addData("王五") System.out.println(myArray3); Object data = myArray3.getData(1); System.out.println(data); } }
java官方 基于数组 根据不同的数据结构 创建了多个类 这些类统称为集合框架。所以我们说结合框架时 就是表示多个类
1.3集合的架构
1.4List集合-ArrayList
1.4.0创建集合对象
//创建一个集合对象 如果没有指定集合容器的长度默认为15
List list = new ArrayList();
List list1 = new ArrayList(15);
1.4.1添加操作
public static void main(String[] args) { ArrayList<Object> aryt = new ArrayList<>(); aryt.add("张三"); aryt.add("张三"); aryt.add(123); aryt.add(null); System.out.println(aryt); //下标为1的位置添加元素 aryt.add(1,"王五无"); System.out.println(aryt); ArrayList<Object> aryt2 = new ArrayList<>(); aryt2.add("java"); aryt2.add("集合"); aryt2.add(333); aryt2.add(222); System.out.println(aryt2); //添加多个元素把aryt中的每个元素一一添加到aryt2中 aryt2.addAll(1,aryt); System.out.println(aryt2); }
1.4.2 删除操作
public static void main(String[] args) { ArrayList<Object> arty = new ArrayList<>(); arty.add("张三"); arty.add(123); arty.add("java"); arty.add(null); System.out.println(arty); //删除下标为0的元素 arty.remove(0); System.out.println(arty); //删除指定元素 boolean remove1 = arty.remove("java"); System.out.println(remove1); System.out.println(arty); //清空集合中的元素 arty.clear(); Syetem.out.println(arty); }
1.4.3修改操作
public void test(){ ArrayList<Object> alt = new ArrayList<>(); alt.add("张三"); alt.add("java"); alt.add(21233); System.out.println(alt); //修改下标为1的元素 alt.set(1,"王五无"); }
1.4.4查询操作
public static void main(String[] args) { ArrayList<Object> alt = new ArrayList<>(); alt.add("java01"); alt.add("java02"); alt.add("java03"); //根据下标获取元素 Object o=alt.get(1); //获取集合中元素的个数 System.out.println(o); int size = alt.size(); System.out.println(size); //判断元素是否在集合中 boolean java05 = alt.contains("java05"); System.out.println(java05); //查询元素在集合中第一次出现的位置 int java03 = alt.indexOf("java03"); System.out.println(java03); //遍历集合中的元素 for循环 for (int i=0;i< alt.size();i++){ Object o1=alt.get(i); System.out.println(o1); } //遍历集合中的元素 forEach循环 for (Object o1:alt){ System.out.println(o1); } }
1.4.5ArrayList底层源码
ArrayList arrayList = new ArrayList(22);
//ArraylIst 底层使用的还是Object类型的数组
//底层无参构造
/*DEFAULTCAPACITY_EMPTY_ELEMENTDATA(默认容量空元素数据)
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}*/
//底层声明了一个Object类型的数组 名字为elementData
//transient Object[] elementData;
//底层有参构造
/*new ArrayList(22) 参数22给了initialCapacity(初始容量)
public TestArrayList(int initialCapacity) {
//判断穿过来的参数是否大于0
if (initialCapacity > 0) {
//将22初始容量赋值给 这个数组长度为22
this.elementData = new Object[initialCapacity];
//如果为0初始化一个空数组
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
//不大于0也不等于0抛出异常
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}*/
//======================add("java01")======E理解为Object类型=============
//底层代码
//将java01 变量给e 相当于给了elementData[size++]数组的响应位置
/*public boolean add(E e) {
//扩容element数组的长度
ensureCapacityInternal(size + 1); // Increments modCount!!
//上面已经扩容了 判断是否扩容 复制完之后size再加加 ++在后 先执行在++
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;
}
//没有找到该元素返回-1
return -1;
}*/
//=====================size()求数组的长度=========================
/*public int size() {
return size;
}*/
//=====================contain("java01")=================
/*public boolean contains(Object o) {
//调用indeOf(o) 将java01传过去 如果数组没有indexOf(o) >= 0 为false 若有返回true
return indexOf(o) >= 0;
}*/
//=======================get(i)获取指定位置的元素===================
/*public E get(int index) {
//rangeCheck(index)方法判断指定位置是否合法 传过来的参数index可能超过下标或为负数
rangeCheck(index);
//调用elementData(index)方法并传参
return elementData(index);
}*/
/*E elementData(int index) {
//返回elementData[index];这个下标的元素
return (E) elementData[index];
}*/
//=================toString()为什么不打印引用对象的地址=============
//重写了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的底层就是基于数组实现的
1.5LinkedList
LinkedList是一个链表结构
1.5.1添加
//LinkedList是链表结构 public static void main(String[] args) { //LinkedList底层不是数组不在指定长度 LinkedList linkedList = new LinkedList(); //不加First Last 默认添加到数组的尾部 linkedList.add("java01"); //添加元素到头部 linkedList.addFirst("java02"); //也重写了toString方法 System.out.println(linkedList); //添加元素到尾部 linkedList.addLast("java03"); //代码从上往下执行 java04在元素的头部 linkedList.addFirst("java04"); //代码从上往下执行 添加元素到尾部 linkedList.addLast("java05"); System.out.println(linkedList); }
1.5.2 删除
//移除头部元素 linkedList.removeFirst(); System.out.println(linkedList); //移除指定下标元素 linkedList.remove(3); //移除尾部元素 System.out.println(linkedList); //清空所有元素 linkedList.clear(); System.out.println(linkedList);
1.5.3修改操作
linkedList.set(2,"张三"); System.out.println(linkedList);
1.5.4查询操作
//查询长度 int size = linkedList.size(); System.out.println(size); //是否为空 boolean empty = linkedList.isEmpty(); System.out.println(empty); //是否含有某元素 boolean contains = linkedList.contains("张三"); System.out.println(contains); //根据下标获取指定位置的元素 Object o = linkedList.get(1); System.out.println(o); //获取第一个元素 Object first = linkedList.getFirst(); System.out.println(first); //获取最后一个元素 Object last = linkedList.getLast(); System.out.println(last);