本文主要是对泛型的初学简单做一个总结吖~
对于常见的泛型模式,推荐的泛型类型变量:
E:元素(Element),多用于java集合框架
K:关键字(Key)
N:数字(Number)
T:类型(Type)(通用)
V:值(Value)
泛型是我们需要的程序设计手段。使用泛型机制编写的程序代码要比那些杂乱地使用Object变量,然后再进行强制类型转的代码具有更好的安全性和可读性。泛型对于集合类尤其有用。
public class ListDemo {
// 集合不使用泛型
public void test1() {
ArrayList list = new ArrayList();
//存放的实际上是integer类型
list.add(12);
list.add(23);
list.add(34);
list.add(45);
//问题一:类型不安全
list.add("Tom");
for (Object score : list) {
//问题二:强转时,可能出现ClassCastException
int stuScore = (Integer) score;
System.out.println(stuScore);
}
}
// 集合使用泛型。
public void test2() {
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(78);
list.add(87);
list.add(99);
list.add(65);
//编译时,就会进行类型检查,保证数据的安全
// list.add("小伙儿");
//方式一:
for(Integer score : list){
// 避免了强转操作
int stuScore = score;
System.out.println(stuScore);
}
//方式二:
Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()) {
int stuScore = iterator.next();
System.out.println(stuScore);
}
}
public static void main(String[] args) {
ListDemo listDemo = new ListDemo();
listDemo.test1();
listDemo.test2();
}
}
当test1()方法中,即添加了int类型的数据,又添加了String数据的时候就会出现如下结果。
结果1:
当test2()方法中,如果使用泛型,会再直接报错,不会再运行时才显示。
泛型程序设计(Generic programming)意味着编写的代码可以被很多不同类型的对象所重用。
泛型方法与泛型类、接口等均无关系。
由下可以看出,不管此类是不是泛型类,泛型方法均与此类是否定义为泛型类无关。
public class GenericMethodDemo {
// 泛型方法
public <T> void show(String t) {
System.out.println("【泛型方法】返回值为void。" + t);
}
public <T> T shows(T t) {
System.out.println("【泛型方法】返回值为泛型");
return t;
}
public static <T> T staticShow(T t) {
System.out.println("【泛型方法】static修饰的泛型方法,返回值为泛型");
return t;
// 不可用
// public static E staticShow(E t) {
// System.out.println("【泛型方法】定义为T的泛型方法,返回值为泛型E时不可用");
// return t;
// }
}
}
静态泛型方法:
public class GenericMethodDemo {
public static <T, E> E staticShow(E t) {
System.out.println("【泛型方法】定义为T、E的泛型方法,返回值可以为任意一个类型,传的参数也可以为两种泛型的一个,但是不能为其它泛型");
return t;
}
public static <T, E> T staticShow(T t) {
return t;
}
public static <T, E> T staticShow(E t) {
T s;
return s;
}
}
代码如下(示例):
//泛型父类
public class GenericDemoFather<M,N> {
M a;
N b;
}
子类处理泛型父类的各种方式如下。
public class GenericDemoSon extends GenericDemoFather<Integer,String>{
// extends继承时明确父类的类型
}
public class GenericDemoSon<M> extends GenericDemoFather<M,String>{
// 父类保持泛化,子类需要保持泛化。
}
public class GenericDemoSon<N> extends GenericDemoFather<Integer,N>{
// 父类保持泛化,子类需要保持泛化。
}
public class GenericDemoSon<M,N> extends GenericDemoFather<M,N>{
// 父类保持完全泛化,子类保持完全泛化。
}
public class GenericDemoSon<M,N> extends GenericDemoFather<N,M>{
// 父类保持完全泛化,子类保持完全泛化。与顺序无关。
}
public class GenericDemoSon<T> extends GenericDemoFather{
// 子类可以拥有自己的泛型
}
public class GenericDemoSon<T,E> extends GenericDemoFather<Integer,String>{
// 父类类型明确,子类仍可以拥有自己的泛型,且不需要保持父类的类型
}
代码如下(示例):
public class GenericMethodDemo {
/**
* 类型变量的限定
* 为什么使用extends,而不用implements?(Comparable是一个接口)
* 其更接近于子类的概念。
*/
// 传入的数组进行最大最小值的比较
public static <T extends Comparable> MaxiAndMinimum<T> minAndmax(T[] arr) {
if (arr == null || arr.length == 0) {
return null;
}
T max = arr[0];
T min = arr[0];
for (int i = 0; i < arr.length; i++) {
if (min.compareTo(arr[i]) > 0) {
//compareTo() 方法用于两种方式的比较
min = arr[i];
}
if (max.compareTo(arr[i]) < 0) {
max = arr[i];
}
}
return new MaxiAndMinimum<>(min, max);
}
}
/**
* 泛型类:求最大最小值的类
*/
class MaxiAndMinimum<T> {
private T mininum;//最小值
private T maxinum;//最大值
//带参的构造函数
public MaxiAndMinimum(T mininum, T maxinum) {
this.mininum = mininum;
this.maxinum = maxinum;
}
@Override
public String toString() {
return "MaxiAndMinimum{" +
"mininum=" + mininum +
", maxinum=" + maxinum +
'}';
}
public T getMininum() {
return mininum;
}
public void setMininum(T mininum) {
this.mininum = mininum;
}
public T getMaxinum() {
return maxinum;
}
public void setMaxinum(T maxinum) {
this.maxinum = maxinum;
}
}
/**
* 测试主类
*/
class GenericTest<T> {
// static 修饰的变量不可以为泛型类型
// public static T data;
public static void main(String[] args) {
showGenericBaseDemo();
GenericTest genericTest = new GenericTest();
genericTest.showMinMaxDemo();//调用求最大最小值方法
}
//自定义泛型方法等的例子
public static <T> void showGenericBaseDemo() {
GenericMethodDemo genericMethodDemo = new GenericMethodDemo();
genericMethodDemo.show("【结果】方法调用传入的参数为String,返回类型未指定");
genericMethodDemo.<String>show("【结果】方法调用传入的参数为String,返回类型指定为String");
System.out.println();
System.out.println("下面的方法,返回类型指定为Object");
System.out.println(genericMethodDemo.<Object>shows(new GenericDemo<Integer>()));
System.out.println(genericMethodDemo.shows(100));
System.out.println(GenericMethodDemo.<Integer>staticShow(123));
}
// 显示一个已知数组的最大最小值
public void showMinMaxDemo() {
// 创建一个数组 求此数组最大最小值
Integer[] arr = {
12, 34, 23, 67, 21, 87, 9};//要使用包装类而不是基本数据类型
System.out.println("===============================");
System.out.println("原数组:");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
System.out.println();
MaxiAndMinimum<Integer> genericMethodDemoArr = GenericMethodDemo.minAndmax(arr);
System.out.println("最小值:" + genericMethodDemoArr.getMininum());
System.out.println("最大值:" + genericMethodDemoArr.getMaxinum());
System.out.println("使用toString方法输出结果。" + genericMethodDemoArr.toString());
System.out.println("==============================");
}
}
结果:
【泛型方法】返回值为void。【结果】方法调用传入的参数为String,返回类型未指定
【泛型方法】返回值为void。【结果】方法调用传入的参数为String,返回类型指定为String
下面的方法,返回类型指定为Object
【泛型方法】返回值为泛型
com.company.day0330.GenericDemo@1b6d3586
【泛型方法】返回值为泛型
100
【泛型方法】static修饰的泛型方法,返回值为泛型
123
原数组:
12 34 23 67 21 87 9
最小值:9
最大值:87
使用toString方法输出结果。MaxiAndMinimum{mininum=9, maxinum=87}
提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。
//student 类
public class Student {
private String name;
private double score;
public Student(String name, double score) {
this.name = name;
this.score = score;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", score=" + score +
'}';
}
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (obj instanceof Student) {
Student s = (Student) obj;
if (this.name.equals(s.getName()) ) {
return true;
}
}
return false;
}
}
public class ListDemo2 {
// 集合的嵌套
public void CollectionNesting(){
// 课程的一个大类subjects- ArrayList
ArrayList<Integer> arrayList = new ArrayList<>();
ArrayList<ArrayList<Student>> subjects = new ArrayList<>();
// 创建小集合 课程班级1 classes1
ArrayList<Student> classes1 = new ArrayList<>();
// 把学生装进课程班级1
classes1.add(new Student("凉凉", 80));
classes1.add(new Student("鲨鲨", 79));
// 创建课程班2 classes2
ArrayList<Student> classes2 = new ArrayList<>();
classes2.add(new Student("杏杏", 73));
classes2.add(new Student("憨憨", 84));
// 把学生放进课程2班
subjects.add(classes1);
subjects.add(classes2);
// 遍历打印
// 一层循环 把课程班找出来
for (ArrayList<Student> classes : subjects) {
// 二层循环 把班里学生找出来
// System.out.println(classes);
for (Student student : classes) {
System.out.print("*");
System.out.println(student);
}
System.out.println("==========");
}
}
public static void main(String[] args) {
ListDemo2 listDemo2 = new ListDemo2();
listDemo2.CollectionNesting();
}
}
上述代码主要是集合的嵌套的一个简单例子,使用泛型编写集合的嵌套就会很清晰并且很好用~
上述结果:
*Student{name=‘凉凉’, score=80.0}
*Student{name=‘鲨鲨’, score=79.0}
==========
*Student{name=‘杏杏’, score=73.0}
*Student{name=‘憨憨’, score=84.0}
==========
本文主要通过上述的例子来对泛型进行一定的了解与认识。当然,泛型还有许多需要学习的知识,尤其是与集合的结合运用是Java开发中一个重要的知识部分。后续还会进行深入学习,这次就先写这些吧~
欢迎留言点赞收藏吖~