Day24 学习分享 - 项目再优化和List集合

1. 项目再优化
1.1 情况分析
目前问题:
	数据存储是数组形式, 数据类型明确, 复用度较低
	
需求:
	Student操作使用的代码, StudentManager不管更换什么数据类型都可以直接使用
	
解决方法:
	1. 泛型
	2. 数组不能使用泛型, 但是这个数组又需要保存各式各样的数据
		使用Object类
1.2 使用泛型和Object数组优化项目

2. List接口
2.1 List接口概述
List接口特征:
	1. 数据存储可重复
	2. 有序, 添加顺序和保存顺序一致
--| ArrayList<E> 可变长数组
--| LinkedList<E> 双向链表
--| Vector<E> 线程安全的可变长数组
2.2 List常用方法
:
    boolean add(E e);
		List接口继承Collection接口 add方法, 使用操作和Collection一致, 并且这里		   采用的添加方式是【尾插法】
	boolean add(int index, E e);
		List接口【特有方法】, 在指定位置添加指定元素
	boolean addAll(Collection<? extends E> c);
		List接口继承Collection接口 addAll方法, 使用操作和Collection一致, 并且		这里采用的添加方式是【尾插法】
	boolean addAll(int index , Collection<? extends E> c);
		List接口【特有方法】, 在指定下标位置添加另一个集合中所有内容
删:
	E remove(int index);
		List接口【特有方法】,获取指定下标位置的元素
	boolean remove(Object obj);
		List接口继承Collection接口方法, 删除集合中的指定元素
	boolean removeAll(Collection<?> c);
		List接口继承Collection接口方法, 删除当前集合中和参数集合重复元素
    boolean retainAll(Collection<?> c);
		List接口继承Collection接口方法, 保留当前集合中和参数集合重复元素
	void clear();
		List接口继承Collection接口方法, 清空整个集合中所有元素
改:
    E set(int index, E e);
		List接口【特有方法】, 使用指定元素替代指定下标的元素, 返回值是被替换的元素
查:  
    int size();
		List接口继承Collection接口方法, 获取集合中的有效元素个数
	boolean isEmpty();
		List接口继承Collection接口方法, 判断当前集合是否为空
	boolean contains(Object obj);
		List接口继承Collection接口方法, 判断指定元素是否包含在当前集合中
	boolean containsAll(Collection<?> c);
		List接口继承Collection接口方法, 判断参数集合是不是当前集合的子集合
	Object[] toArray();
		List接口继承Collection接口方法, 获取当前集合中所有元素的Object数组

	E get(int index);
		List接口【特有方法】, 获取指定下标对应的元素
	List<E> subList(int fromIndex, int toIndex);
		List接口【特有方法】, 获取当前集合的子集合, 从fromIndex开始到toIndex结			束, fromIndex <= 范围 < toIndex, 要头不要尾
	int indexOf(object obj);
		List接口【特有方法】, 获取指定元素在集合中第一次出现的位置
	int lastIndexOf(Object obj);
		List接口【特有方法】, 获取指定元素在集合中最后一次出现的位置
2.3 List接口常用方法演示
package com.qfedu.a_list;

import java.util.ArrayList;
import java.util.List;

public class Demo1 {
	public static void main(String[] args) {
		/*
		 * List<E>是一个接口, 没有自己的类对象, 这里使用List接口的
		 * 实现类对象ArrayList来演示代码
		 */
		List<String> list = new ArrayList<String>();
		
		list.add("浓郁咖啡拿铁");
		list.add("浓郁咖啡摩卡");
		list.add("焦糖玛奇朵");
		list.add("摩卡可可碎星冰乐");
		list.add("可可卡布奇诺");
		
		System.out.println(list);
		
		list.add(3, "美式咖啡");
		
		System.out.println(list);
		
		List<String> list2 = new ArrayList<String>();
		
		list2.add("肥宅快乐水");
		list2.add("芬达");
		list2.add("雷碧");
		list2.add("冰峰");
		
		list.addAll(4, list2);
		
		System.out.println(list);
		
		String remove = list.remove(1);
		System.out.println(remove);
		System.out.println(list);
	}
}
package com.qfedu.a_list;

import java.util.ArrayList;
import java.util.List;

public class Demo2 {
	public static void main(String[] args) {
		/*
		 * List<E>是一个接口, 没有自己的类对象, 这里使用List接口的
		 * 实现类对象ArrayList来演示代码
		 */
		List<String> list = new ArrayList<String>();
		
		list.add("浓郁咖啡拿铁");
		list.add("浓郁咖啡摩卡");
		list.add("焦糖玛奇朵");
		list.add("摩卡可可碎星冰乐");
		list.add("可可卡布奇诺");
		list.add("肥宅快乐水");
		list.add("芬达");
		list.add("雷碧");
		list.add("冰峰");
		list.add("浓郁咖啡拿铁");
		list.add("浓郁咖啡摩卡");
		list.add("焦糖玛奇朵");
		list.add("摩卡可可碎星冰乐");
		list.add("可可卡布奇诺");
		list.add("肥宅快乐水");
		list.add("芬达");
		list.add("雷碧");
		list.add("冰峰");
		
		
		String str = list.set(3, "细思极恐");
		System.out.println(str);
		System.out.println(list);
		
		str = list.get(1);
		System.out.println(str);
		System.out.println(list);
		
		/*
		 * 从指定位置开始, 到目标位置结束, 获取对应的子集合
		 */
		List<String> subList = list.subList(2, 5);
		System.out.println(subList);
		
		int index = list.indexOf("芬达");
		System.out.println(index);
		
		index = list.lastIndexOf("芬达");
		System.out.println(index);
	}
}
3. ArrayList【重点】
3.1 ArrayList概述
	ArrayList是在Java中集合非常重要的一个组成, 基于数组完成的数据结构. 可变长数组操作. 
	底层保存数据的是一个Object类型数组
	ArrayList使用的方法都是List接口中的方法, 有两个需要了解的成员方法:
		ensureCapacity();
			判断方法, 用于确定当前底层数组的容量是否满足当前操作的需求.
		trimToSize();
			节省空间, 将底层数组的容量缩容至有效元素个数
			
	需要掌握的是关于ArrayList效率相关的问题和细节问题
3.2 细节问题
1. DEFAULT_CAPACITY
	默认容量 private static final int DEFAULT_CAPACITY = 10;
	在调用ArrayList无参数构造方法时才会使用DEFAULT_CAPACITY, 作为底层Object数组的初始化容量. 如果用户指定调用的是带有初始化底层Object数组容量的构造方法, 会根据用户指定的容量创建一个ArrayList集合.
        
2. MAX_ARRAY_SIZE ==> Integer.MAX_VALUE - 8;
	int[] arr = new int[10]
        
        arr.length 是什么?  数组容量
        这里是一个方法还是属性? 属性
        属性是不是成员变量? 是
        成员变量是否需要占用内存? 需要
        
        new 数组占用的空间在哪里? 堆区
        arr.length 属性是不是也在堆区? 是
        
        为什么 - 8?
        	因为在数组中存在很多属性, length只是众多属性中的一个, 在创建数组使用的过程中, 需要留有内存空间用于保存数组中的属性
3.3 效率问题
ArrayList特征:
	增删慢:
		增加慢:
			1. 数组当前容量无法满足添加操作, 需要进行grow扩容方法执行, 在扩容方法			   中存在数组的创建, 数组数据拷贝, 非常浪费时间而且浪费内存
			2. 数组在添加数据的过程中, 存在在指定位置添加元素, 从指定位置开始之后				 的元素整体向后移动
		删除慢:
			1. 删除数据之后, 从删除位置开始之后的元素整体向前移动, 移动过程非常浪				 费时间
			2. 删除操作会导致数据空间的浪费, 内存的浪费
	查询快:
		ArrayList底层是一个数组结构, 在查询操作的过程中, 是按照数组+下标的方式来			操作对应的元素, 数组+下标的方式可以直接获取对应的空间首地址,CPU访问效率极高
3.4 【补充知识点, 内存地址】
内存地址概念:
	[计算机原理]
	计算机中为了更好地使用内存, 操作程序, 完成代码, 将内存按照最小单位, 进行了编号处理.
	最小单位: 字节 byte
	从编号为0内存开始, 到内存的最大值. 地址的展示方式是十六进制
	
生活案例:
	邮政编码!
	郑州银屏路115号
	航海中路60号
		编号具有唯一性, 精确定位, 精确指向
	在软件开发中就是采用类似于生活中小区, 工厂编号模式, 在一条路中对每一个单位进行编号处理.
	
	以32G内存为例
		0x0 ~ 0x7 FFFF FFFF
3.5 【补充知识点 内存地址对于CPU有什么关系】
生活案例:
	快递小哥, 可以根据地质直接高效送快递到你家, 根据地址来处理快递
	
	快递小哥可以看做CPU, 快递去地址, 具有唯一性!
	
代码实际运行:
	CPU就是根据内存地址, 可以直达内存所在区域, 执行对应代码. 精准而优雅, 速度非常快
3.6 【补充知识点 数组空间地址关系】

在这里插入图片描述

3.7 【补充知识点 null到底是什么】
null 是计算机中非常特殊的一块内存, 该内存编号 0x0000 0000

该内存受到系统保护
	不只是电脑, 包括手机 Ipad 智能设备, 只要存在计算机基本结构的设备上都存在null 编号为0x0内存, 大小一个字节
	该内存不能读取任何数据, 也不能写入任何数据, 一旦操作, 程序直接被系统杀死
	Kill -9
	
	一般用于引用数据类型的初始化, 利用开发中关于null的异常辅助找出代码中的错误.
	NullPointerException. 空指针异常
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值