Java Day30

泛型

泛型其实也是一种归纳总结思想的提升,对于数据处理的范围,参数的类型,方法操作的数据… 进行了二次剥离!!

作用
代码中使用泛型之后,可以极大的提高对于代码的复用性,可移植性,可操作性。

格式

Java中泛型规定:
<自定义无意义英文大写单字母占位符>
一般常用:
Type
Element
Key
Value
泛型可以约束
方法

接口

包装类

Java中数据类型其实是分两大类
1. 基本数据类型
byte short int long float double char boolean
2. 引用数据类型

Java中有一个概念
万物皆对象。
所以Java中对于基本数据类型也做了封装,完成了对于基本数据类型的【包装类】

基本数据类型对应的包装类
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean
1. 包装类的使用,可以满足Java中万物皆对象的操作规范,让代码操作更加统一化
2. 包装类中对于数据类型提供了一定的【解析方法】,这些方法是需要我们学习的
3. 包装类使用不会增加我们开发的压力,因为Java中提供了【自动包装】和【自动拆箱】

自动包装和自动拆箱

泛型在方法中使用

格式:
权限修饰符 [static] <自定义泛型> 返回值类型 方法名(形式参数列表) {

}
【重点】
	1. 要求形式参数列表中必须有一个参数是当前自定义泛型,因为需要通过参数来约
	束当前方法运行过程中泛型对应的具体数据类型是哪一个。
	
	2. 返回值类型可以使用自定义泛型,而且是被形式参数列表中传入的泛型对应具体
	数类型控制
	
	3. 方法体内也可以使用自定义泛型,同时也是被参数当中泛型对应具体数据类型约
	束监控

package com.qfedu.a;

/*

  • 自定义泛型在方法中使用【重点】
    */
public class Demo2 {
	public static void main(String[] args) {
		// <Integer> Integer com.qfedu.a.Demo2.getType(Integer t)
		Integer type = getType(1);
		
		Float type2 = getType(3.14F);
		
		Demo2 type3 = getType(new Demo2());
		
		String type4 = getType("这方法有点东西哦~~~~");	
	}
	
	/**
	 * 带有自定义泛型 T 对应的方法
	 * 
	 * @param <T> 自定义泛型无意义英文单个大写字母占位符
	 * @param t T类型
	 * @return T类型
	 */
	public static <T> T getType(T t) {
		return t;
	}
}

自定义泛型使用案例

package com.qfedu.a;

/*
 * 自定义泛型在方法中使用案例
 */
public class Demo3 {
	public static void main(String[] args) {
		printEverything(1);
		printEverything(3.14);
		printEverything(3.14F);
		printEverything("想啥来啥~~~~");
		
		printAnyTypeArray(new Integer[10]);
		printAnyTypeArray(new String[10]);
		printAnyTypeArray(new Demo3[10]);
	}
	
	/*
	 * 需求
	 * 		完成一个可以满足任意类型展示的方法
	 */
	public static <T> void printEverything(T t) {
		System.out.println(t);
	}
	
	/*
	 * 需求
	 * 		完成一个方法可以满足展示任意类型数组
	 */
	public static <T> void printAnyTypeArray(T[] arr) {
		for (int i = 0; i < arr.length; i++) {
			System.out.println(arr[i]);
		}
	}
	
	/*
	public static void printIntArray(int[] arr) {
		for (int i = 0; i < arr.length; i++) {
			System.out.println(arr[i]);
		}
	}
	
	public static void printDoubleArray(double[] arr) {
		for (int i = 0; i < arr.length; i++) {
			System.out.println(arr[i]);
		}
	}
	*/
	
	/*
	 * 一下方法操作过程是一致的,处理方式是一致的,只有参数类型不一样
	 * 封装 升华参数类型,使用泛型替代
	
	public static void printInt(int i) {
		System.out.println(i);
	}
	
	public static void printDouble(double d) {
		System.out.println(d);
	}
	
	public static void printFloat(float f) {
		System.out.println(f);
	} 
	*/
}

Object和泛型的比较

package com.qfedu.a;

/*
 * Object和泛型的对比
 *
 */
public class Demo4 {
	public static void main(String[] args) {
		/*
		 * Object参数操作
		 * 代码中所有的返回值都是Object类型,然后需要操作对应的真实类型
		 * 要求完成强制类型转换,操作对于数据没有影响,但是有点繁琐
		 */
		Object type = getType(1);
		Object type2 = getType("你好");
		Object type3 = getType(new Demo1());
		
		
		/*
		 * 泛型参数操作
		 * 泛型约束之后,返回值类型就是对应的具体数据类型,不需要强制类型
		 * 转换操作,提高了开发效率
		 */
		Integer type22 = getType2(1);
		String type23 = getType2("你好");
		Demo1 type24 = getType2(new Demo1());
		
	}
	
	public static Object getType(Object obj) {
		return obj;
	}
	
	public static <T> T getType2(T t) {
		return t;
	}
}

泛型在类中的使用

有那么一大堆方法都要使用泛型,而且这些方法还有一定的关联性。使用类【封装】这些方法,将泛型的声明用于类名上,做到一个统一的约束过程。
【始终强调的是方法!!!】

格式:
class 类名<自定义泛型无意义英文大写单个字母占位符> {
// 成员变量不推荐使用泛型,存在一定的隐患,操作不方便
// 成员方法可以使用类名声明的自定义泛型
// 静态成员方法是个坑!!!
}

类名使用泛型约束具体数据类型的格式【重点】
案例:
class Demo {

	}
Eclipse:
	类名<具体数据类型> 类对象 = new 构造方法<具体数据类型>();
	例:
		Demo<String> demo = new Demo<String>(); √标准格式
		Demo<String> demo = new Demo<Integer>(); 类型不一致报错 ×
		Demo<Object> demo = new Demo<String>(); 类型不一致报错 ×

IDEA:
	类名<具体数据类型> 类对象 = new 构造方法<>();
	例如:
		Demo<String> demo = new Demo<>(); √标准格式
package com.qfedu.a;

/*
 * 类声明带有自定义泛型演示 
 * <T> 声明自定义泛型T
 */
class Demo<T> {
	/*
	 * 在带有泛型的类内,成员方法可以直接使用类声明的自定义泛型
	 */
	public void test1(T t) {
		System.out.println(t);
	}
	
	public T test2(T t) {
		return t;
	}
}

public class Demo5 {
	public static void main(String[] args) {
		/*
		 * 约束泛型的具体数据类型是String类型
		 * 
		 * 类内所有的成员方法中使用到泛型的位置都是String类型
		 */
		Demo<String> demo = new Demo<String>();
		
		demo.test1("你好");
		String test2 = demo.test2("大家好");
		
	
		/*
		 * 泛型约束当前 d 对象中所有的泛型都是Demo1类型
		 */
		Demo<Demo1> d = new Demo<Demo1>();
		d.test1(new Demo1());
		Demo1 test22 = d.test2(new Demo1());
		
		
		/*
		 * 未使用具体数据类型来约束对应的泛型
		 * 
		 * 当前d1调用所有类内使用泛型的方法,泛型对应的具体数据类型
		 * 都会变成Object类型,这样就有有悖于泛型的操作要求。
		 */
		Demo d1 = new Demo();	
	}
}
  1. 类内的成员方法可以直接使用对应的类名声明泛型
  2. 类内成员方法使用的泛型具体数据类型是在创建当前类对象是约束。
  3. 在创建当前类对象时没有约束泛型对应的具体数据类型,那么所有使用到泛型的位置都是Object类型,有悖于泛型使用原则
  4. 类中使用泛型,是在满足代码普适性的情况下,有可以兼顾数据类型一致化要求。有的放矢

泛型在接口中使用

接口:
成员变量:
缺省属性: public static final
定义时必须初始化
成员方法:
缺省属性: public abstract
该方法没有方法体

泛型在接口中使用的格式:
interface 接口名<自定义泛型无意义英文单个字母大写占位符> {
自定义泛型有且只能给方法使用!!!
}
【接口中的成员变量不能使用自定义泛型】
1. 成员变量缺省属性public static final 定义时必须初始化,但是泛型初始
化为什么???
没有具体的数据类型,无法进行初始化操作
2, 成员变量static修饰,当前成员变量需要在加载阶段,明确所有内容,但是当
前情况下,数据类型不明确的。
有悖于语法的!!!

学生管理项目完善

package com.qfedu.student.system.myexception;

/**
 * 自定义异常,用于创建StudentManager对象时
 * 用户传入的初始化容量不合法操作!抛出异常处理!!!
 * 
 * @author Anonymous
 *
 */
public class IllegalCapacityException extends Exception {

	private static final long serialVersionUID = 1L;

	public IllegalCapacityException() {}
	
	public IllegalCapacityException(String message) {
		super(message);
	}
}



package com.qfedu.student.system.myexception;

/**
 * 自定义异常,用于在StudentManager对象底层数组扩容的过程
 * 发现数组的容量超出了最大数组要求
 * @author Anonymous
 *
 */
public class OverflowMaxArraySizeException extends Exception {
	
	private static final long serialVersionUID = 1L;

	public OverflowMaxArraySizeException() {
	}

	public OverflowMaxArraySizeException(String message) {
		super(message);
	}
}


package com.qfedu.student.system.compare;

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

public interface StudentCompare {
	/*
	 * 接口要求的方法分析
	 * 		返回值:
	 * 			boolean
	 * 		方法名:
	 * 	 		compare
	 * 		形式参数列表: 
	 * 			需要两个学生对象
	 * 			(Student stu1, Student stu2)
	 * 方法声明:
	 * 		boolean compare(Student stu1, Student stu2)
	 */
	/**
	 * 要求实现类完成的比较两个学生类对象的方法,具体的比较方式由实现类决定
	 * 
	 * @param stu1 Student类型
	 * @param stu2 Student类型
	 * @return 比较结果返回boolean
	 */
	boolean compare(Student stu1, Student stu2);
}


/**                                                         
 * 按照成绩升序排序的算法                                              
 *                                                          
 * @param com 这里需要的参数类型是StudentCompare接口,要求传入的              
 * 			对象是StudentCompare接口实现类对象                        
 */                                                         
public void sortUsingCompare(StudentCompare com) {          
	/*                                                      
	 * 排序算法操作不能在原数据数组中进行直接操作,需要另外准备                         
	 * 一个用于排序的临时数组,这里就涉及到一个数据拷贝过程。                          
	 */                                                     
	Student[] sortTemp = new Student[size];                 
	                                                        
	for (int i = 0; i < sortTemp.length; i++) {             
		sortTemp[i] = allStus[i];                           
	}                                                       
	                                                        
	for (int i = 0; i < sortTemp.length - 1; i++) {         
		                                                    
		// 找出极值                                             
		int index = i;                                      
		                                                    
		for (int j = i + 1; j < sortTemp.length; j++) {     
			// 按照成绩升序排序                                     
			// 使用接口中规定的方法,替换比较规则!!!                         
			if (com.compare(sortTemp[index], sortTemp[j])) {
				index = j;                                  
			}                                               
		}                                                   
		                                                    
		// 交换位置                                             
		if (index != i) {                                   
			Student stu = sortTemp[index];                  
			sortTemp[index] = sortTemp[i];                  
			sortTemp[i] = stu;                              
		}                                                   
	}                                                       
	                                                        
	for (int i = 0; i < sortTemp.length; i++) {             
		System.out.println(sortTemp[i]);                    
	}                                                       
	                                                        
}                              


package com.qfedu.student.system.compare.impl;

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

/**
 * 学生成绩升序排序要求
 * 是StudentCompare接口的实现类对象
 * 
 * @author Anonymous
 *
 */
public class ScoreAscCompare implements StudentCompare {

	@Override
	public boolean compare(Student stu1, Student stu2) {
		return stu1.getScore() > stu2.getScore();
	}

}         
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值