Day23 学习分享 - 项目优化和集合

1. 项目优化
1.1 目标
1. 完成数据展示过滤功能
2. 完成数据的字符串处理过程
1.2 使用接口完成按照条件过滤展示数据的方式
分析:
	for(遍历保存数据的数组) {
		if (条件过滤) {
			展示
		}
	}

	返回值类型:
		boolean
	方法名:
		accept
	形式参数列表:
		一个Student学生类对象

interface StudentFilter {
	boolean accept(Student stu);
}
package com.qfedu.student.system.filter;

import com.qfedu.student.system.entity.Student;

public interface StudentFilter {
	/**
	 * 判断一个Student类对象能否满足条件, 满足条件返回true, 否则返回false
	 * 条件判断由实现类完成
	 * 
	 * @param student 学生类对象
	 * @return 判断满足条件否的结果
	 */
	boolean accept(Student student);
}
package com.qfedu.student.system.filter.impl;

import com.qfedu.student.system.entity.Student;
import com.qfedu.student.system.filter.StudentFilter;

public class StudentFilterImpl implements StudentFilter{

	@Override
	public boolean accept(Student student) {
		
		return student.getAge() > 15;
	}
}
/**
	 * 展示学生信息, 但是要求学生信息满足过滤器要求
	 * 
	 * @param filter 过滤器接口, 要求传入的是StudentFilter接口实现类对象
	 */
	public void filterStudentInfo(StudentFilter filter) {
		for (int i = 0; i < size; i++) {
			if(filter.accept(allStus[i])) {
				System.out.println(allStus[i]);
			}
		}
	}
1.3 完成数据的字符串处理过程
1.3.1 对于数据处理的基本理念
开发中, 数据的存储是很大一部分内容
	马云 --> 得数据者得天下
	最小的方式储存最多的数据
	
	程序数据 ==> 字符串 ==> 文件
	文件 ==> 字符串 ==> 程序数据
1.3.2 程序数据 ==> 字符串
Student [name=骚磊, age=16, id=1, gender=男, score=100]

需要保存的数据是:
	骚磊 16 1 男 100....
	每一个数据都有对应的指向性

数据对应的名称不需要保存
	但是
	需要约束好数据的存储和解析规范
	类似于真实开发场景中的接口概念, 也就是规范化数据传输格式
	
保存数据
	骚磊 16 1 男 100 ==> 骚磊,16,1,男,100 ==> String
	"+"  万能胶水
/**
	 * 获取Student类对象中数据的字符串形式
	 * 
	 * @return Student信息字符串
	 */
	public String getStudentData() {
		return id +","+ name +","+ age +","+ gender +","+ score;
	}
1.3.3 字符串 ==> 程序数据
字符串
	11,骚磊,166,,60
	==> Student 对象

1. split(",")
	==> String类型的数组{"11", "骚磊", "166", "男", "60"}
2. id age score ==> int类型
3. 包装类
	Byte Short Integer Long Float Double Character Boolean
	【解析方法】
	存在将字符串数据 ==> 对应类型的方法。

方法
	放在那里???那里类内???
		目前该方法存放在Student类内,暂时存放,后期考虑完成一个数据处理类(DAO)
	方法权限修饰符
		publicprivate 不可以
	是否需要使用static修饰
		成员方法	
			需要通过类对象来进行操作解析完成
			该方法使用场景是在代码的启动阶段从文件中读取字符串数据之后,解析字符串内容
		静态成员方法 √
			通过类名直接调用,做成一个工具方法,操作更加方便,摆脱类对象约束
	返回值类型:
		Student
	方法名:
		parseStudent
	形式参数列表:
		String str

方法声明:
	public static Student parseStudent(String str);
/**                                                   
 * 解析学生信息字符串,转换成一个Student类对象返回                        
 *                                                    
 * @param str 包含Student信息指定格式字符串                      
 * @return Student类对象                                 
 */                                                   
public static Student parseStudent(String str) {      
	// "11,骚磊,166,男,60"                               
	                                                  
	// 1. split 按照逗号分隔                                
	String[] split = str.split(",");                  
	                                                  
	// {"11","骚磊","166","男","60"}                     
	// Integer.parseInt(String str) 字符串 ==> int类型数据   
	int id = Integer.parseInt(split[0]);              
	String name = split[1];                           
	int age = Integer.parseInt(split[2]);             
	char gender = split[3].charAt(0);                 
	int score = Integer.parseInt(split[4]);           
	                                                  
	/*                                                
	Float.parseFloat(s)                               
	Double.parseDouble(s)                             
	Boolean.parseBoolean(s)                           
	*/                                                
	                                                  
	return new Student(id, name, age, gender, score); 
}                                                     
2. 集合
2.1 集合概述
目前代码中对于多个数据处理过程中, 我们采用的方式是数组方式
	数组操作存在的问题:
		1. 复用度差
			目前对于数据操作有且只能支持一个数据类型, 一旦需要操作其他类型, 全部重			 构, 从头来过
		2. 空间固定
			数组的空间一旦在创建过程中确定, 空间无法修改
		3. 方法较少
			add remove modify get...
			方法自己实现, 没有复用度. Java中对于数组操作没有提供太多的有效方法
			
以上问题集合都可以解决
	1. 复用性
	集合创建采用了泛型模式, 可以用于指定任意类型操作, 既满足普适性, 又满足数据类型一 	致化要求
	2. 空间在合理范围以内自行扩展, 不需要考虑容量问题
	3. 方法很多, 操作性很好 
2.2 集合架构
interface Collection<E> Java中所有集合的总接口
--| interface List<E> List接口, 数据存储可重复, 有序
---| class ArrayList<E> 【重点】 可变长数组
---| class LinkdedList<E> 【重点】 双向链表模式
---| class Vector<E> 线程安全的可变长数组
--| interface Set<E> Set接口, 数据存储不可重复, 无序
---| HashSet<E> 底层存储数据的结构时一个哈希表, 存储效率查询效率极高!
---| TreeSet<E> 底层数据储存的结构是一个平衡二叉树结构, 要求数据必须有比较方式
2.3 Collection接口下的常用方法
:
	boolean add(E e);
		添加当前集合约束的指定数据类型到当前集合中
	boolean addAll(Collection <? extends E> c);
		添加另一个集合到当前集合中, 要求添加集合中保存的元素必须是当前集合中保存元素本身或者其子类对象 【泛型的上限】
		class Dog extends Animal
		class Cat extends Animal
		class Tiger extends Animal:
	boolean remove(Object obj);
		删除集合中指定的元素, 删除成功返回true, 未找到指定元素无法删除返回fasle
		并且在多个元素的情况下, 删除找到的第一个元素
	boolean removeAll(Collection<?> c);
		在当前集合中删除两个集合的交集
	boolean retainAll(Collection<?> c);
		在当前集合中保留两个集合的交集
	void clear();
		清空整个集合中的所有元素
改:
	int size();
		有效元素个数
	boolean isEmpty();
		判断当前集合是否为空,是否存在有效元素
	boolean contains(Object obj);
		判断指定元素是否在当前集合中存在
	boolean containsAll(Collection<?> c);
		判断传入的参数集合是不是当前集合的子集合
	Object[] toArray();
    	返回集合中所有保存元素的Object类型数组
package com.qfedu.a_collection;

import java.util.ArrayList;
import java.util.Collection;

/*
 * Collection集合操作
 */
public class Demo1 {
	public static void main(String[] args) {
		/*
		 * Collection是一个接口, 接口没有自己的类对象, 这里使用Collection接口的实现类ArrayList来演示方法
		 * 接口引用数据类型变量 指向 遵从接口的实现类对象, 这就是多态
		 */
		Collection<String> c1 = new ArrayList<String>();
		
		/*
		 * Add方法
		 */
		
		c1.add("烤羊排");
		c1.add("烤羊肉串");
		c1.add("烤韭菜");
		c1.add("烤大茄");
		c1.add("烤牛肉串");
		
		System.out.println(c1);
		
		Collection<String> c2 = new ArrayList<String>();
		
		c2.add("新密炒虾尾");
		c2.add("炒方便面");
		c2.add("炒饼丝");
		c2.add("干炒牛河");
		
		c1.addAll(c2);
		
		System.out.println(c1);
		
		/*
		 * 删除方法
		 */
		
		c1.remove("炒方便面");
		c1.remove("炒饼丝");
		
		System.out.println(c1);
		
		Collection<String> c3 = new ArrayList<String>();
		
		c3.add("烤羊排");
		c3.add("新密炒虾尾");
		c3.add("干炒牛河");
		c3.add("黄金蛋炒饭");
		
		// 删除两个集合的交集
		// c1.removeAll(c3);
		
		// 保留两个集合的交集
		// c1.retainAll(c3);
		 
		 System.out.println(c1);
	}
}
package com.qfedu.a_collection;

import java.util.ArrayList;
import java.util.Collection;

public class Demo2 {
	public static void main(String[] args) {
		Collection<String> c1 = new ArrayList<String>();
		
		/*
		 * Add方法
		 */
		
		c1.add("烤羊排");
		c1.add("烤羊肉串");
		c1.add("烤韭菜");
		c1.add("烤大茄");
		c1.add("烤牛肉串");
		
		// 获取有效元素个数
		int size = c1.size();
		System.out.println(size);
		
		// c1.clear();
		
		// 判断当前集合是否为空
		System.out.println(c1.isEmpty());
		
		System.out.println(c1.contains("黄金蛋炒饭"));
		System.out.println(c1.contains("烤羊排"));
		
		Collection<String> c2 = new ArrayList<String>();
		
		c2.add("烤羊排");
		c2.add("烤羊肉串");
		c2.add("烤韭菜");
		c2.add("干炒牛河");
		System.out.println(c1.containsAll(c2));
		
		Object[] array = c1.toArray();
		
		for (int i = 0; i < array.length; i++) {
			System.out.println(array[i]);
		}
	}
}
2.4 泛型上限
问题:
	<? extends E>
	class Animal
	--| class Dog extends Animal
	--| class Cat extends Animal
	--| class Tiger extends Animal
	? 替代Dog Cat Tiger
	E ==> Animal

?是泛型的通配符
package com.qfedu.a_collection;

import java.util.ArrayList;
import java.util.Collection;

class Animal {
	
}

class Dog extends Animal {
	
}

class Cat extends Animal {
	
}

class Flower {
	
}

/*
 * 泛型上限演示
 */

public class Demo3 {
	public static void main(String[] args) {
		Collection<Animal> c1 = new ArrayList<Animal>();
		Collection<Dog> c2 = new ArrayList<Dog>();
		Collection<Cat> c3 = new ArrayList<Cat>();
		Collection<Flower> c4 = new ArrayList<Flower>();		
		/*
		 * 当前方法所需的参数类型是Collection<? extends Animal>
		 * 
		 * 要求参数是一个Collection集合
		 * 要求Collection集合中保存的元素是Animal本身或者其子类对象
		 */
		c1.addAll(c1);
		c1.addAll(c2);
		c1.addAll(c3);
		
		/*
		 * c4对应的数据类型是Collection<Flower>
		 * 满足当前方法所需数据类型必须是Collection集合但是
		 * 不满足当前集合中保存元素是Animal本身或者其子类对象的需求
		 * 所以参数错误
		 */
		c1.addAll(c4);
		
	}
}
2.5 泛型通配符
	boolean removeAll(Collection<?> c);
		在当前集合中删除两个集合的交集
	boolean retainAll(Collection<?> c);
		在当前集合中保留两个集合的交集
	boolean containsAll(Collection<?> c);
		判断传入的参数集合是不是当前集合的子集合
		
	? 在当前情况下描述的场景为, 不限制传入参数Collection集合中的保存元素
	这里只要求参数类型是Collection, 里面保存元素无所谓
2.6 集合使用迭代器
2.6.1 迭代器概述和操作模式
	迭代器是操作集合中元素的第二种方式,后期可以延展使用到很多地方,并且存在一个升级版内容。【增强for循环】
	迭代器和集合本身有着密切关系,首先迭代器的获取,就是通过集合对象得到对应当前集合的迭代器。
	获取迭代器方法:
		Iterator<E> iterator();
			获取迭代器对象,泛型对应的具体数据类型和集合中约束的泛型具体数据类型
			一致。
	迭代器操作使用到的方法:
		boolean hasNext();
			判断当前集合中是否可以继续得到元素,继续遍历。
		E next();
			1. 获取迭代器当前指向的元素
			2. 将迭代器指向下一个元素
		void remove();
			删除通过next方法获取到元素
			【注意事项】
				1. remove方法只能删除next方法获取到元素
				2. remove方法只能在next方法之后执行,且不能跨过一个next执行
				3. 没有next不能使用remove

在这里插入图片描述

2.6.2 迭代器操作集合
package com.qfedu.b_iterator;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/*
 * 迭代器操作
 */
public class Demo1 {
	public static void main(String[] args) {
		Collection<String> c = new ArrayList<String>();
		
		c.add("雪花纯生");
		c.add("修道院啤酒");
		c.add("1664");
		c.add("泰山精酿");
		c.add("时光精酿");
		
		System.out.println(c);
		
		/*
		 * 获取对应当前集合的迭代器对象
		 * 集合中保存元素是什么类型,迭代器操作元素就是什么类型
		 * 
		 * 迭代器在获取的过程中,默认指向集合中的第一个元素
		 */
		Iterator<String> iterator = c.iterator();
		
		System.out.println("hasNext()方法演示:" + iterator.hasNext());
		System.out.println("next()方法演示:" + iterator.next());
		System.out.println("next()方法演示:" + iterator.next());
		
		System.out.println("remove()执行");
		// 指向迭代器remove方法
		iterator.remove();
		// iterator.remove();
		
		System.out.println(c);
	}
}
package com.qfedu.b_iterator;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class Demo2 {
	public static void main(String[] args) {
Collection<String> c = new ArrayList<String>();
		
		c.add("雪花纯生");
		c.add("修道院啤酒");
		c.add("1664");
		c.add("泰山精酿");
		c.add("时光精酿");
		
		Iterator<String> iterator = c.iterator();
		
		while (iterator.hasNext()) {
			String string = (String) iterator.next();
			System.out.println(string);
			iterator.remove();
		}
		
		System.out.println(c);
		System.out.println(c.isEmpty());
	}
}
2.6.3 迭代器和集合引用数据类型变量冲突问题
package com.qfedu.b_iterator;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class Demo3 {
	public static void main(String[] args) {
		Collection<String> c = new ArrayList<String>();
		
		c.add("雪花纯生");
		c.add("修道院啤酒");
		c.add("1664");
		c.add("泰山精酿");
		c.add("时光精酿");
		
		/*
		 * 根据当前集合, 获取对应的迭代器对象
		 * 
		 * 得到的迭代器对象会依据当前集合中的所有元素进行一个规划操作
		 * 迭代器对于整个集合中的元素都是存在预期
		 */
		Iterator<String> iterator = c.iterator();
		
		/*
		 * 迭代器遍历, 利用迭代器的特征进行遍历操作
		 */
		while (iterator.hasNext()) {
			// 获取每一个迭代器指向元素, 并且展示
			String string = (String) iterator.next();
			System.out.println(string);
			
			/*
			 * 通过集合对象本身删除1664, 对于迭代器而言, 一脸懵逼, 原本的规划没有了
			 * 并且集合没有告知迭代器数据发生了改变, 迭代器继续按照原本的规划路线操作, 报错
			 * 
			 * 对于集合在内存中占用的空间而言
			 * 1. 集合对应的引用数据类型变量可以操作对应空间
			 * 2. 迭代器可以操作对应的空间
			 * 
			 * 对于集合和迭代器而言, 【集合在内存中占用的空间】是一个【共享资源】
			 * 在操作共享资源过程中, 要多多考虑共享资源的冲突问题
			 * 后面课程中会讲到【多线程】
			 */
			c.remove("1664");
			
			/*
			 * Exception in thread "main" java.util.ConcurrentModificationException
					at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
					at java.util.ArrayList$Itr.next(Unknown Source)
					at com.qfedu.b_iterator.Demo3.main(Demo3.java:24)
			 */
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值