目录
泛型
模拟数据进栈出栈(先进后出)
int类型的数据进栈出栈模拟
package 泛型;
public class Stack {
//定义数组
private int[] arr;
private int i = -1;
public Stack(int size){
arr = new int[size];
}
//添加数据
public void add(int value){
i++;
arr[i] = value;
}
//输出数据
public int get(){
return arr[i--];
}
}
String类型的数据入栈出栈模拟
package 泛型;
public class StringStack {
//定义数组
private String[] S;
private int i = -1;
public StringStack(int size){
S = new String[size];
}
//添加数据
public void add(String value){
i++;
S[i] = value;
}
//输出数据
public String get(){
return S[i--];
}
}
测试类
package 泛型;
public class Test {
public static void main(String[] args) {
Stack stack =new Stack(10);
stack.add(1);
stack.add(2);
stack.add(3);
stack.add(4);
System.out.println(stack.get());
System.out.println(stack.get());
System.out.println(stack.get());
System.out.println(stack.get());
StringStack stringStack = new StringStack(5);
stringStack.add("保定");
stringStack.add("上海");
stringStack.add("北京");
System.out.println(stringStack.get());
System.out.println(stringStack.get());
System.out.println(stringStack.get());
}
}
输出结果:
4
3
2
1
北京
上海
保定
如果还要实现布尔类型,浮点类型的数据进栈出栈呢?难道还需要再定义booleanStack和floatStack吗,有点太麻烦了,这种情况下我们可以选择使用泛型。
1.泛型是什么
泛型:指的就是一切类型,就是说所有类型都能这里进行一个转换。
2.泛型的好处
- 类型安全:使用泛型可以避免类型转换的错误,因为编译器会在编译期间检查类型安全。
- 消除代码冗余:你可以编写与类型无关的代码,通过泛型来指定具体的类型。
- 提高性能:在泛型出现之前,我们通常使用Object来作为参数类型,然后在方法内部进行类型转换。使用泛型可以避免这种不必要的类型转换,从而提高性能。
3.泛型的定义
在Java中,泛型是通过在类或接口后添加一对尖括号(< >
)并在其中指定类型参数来定义的。这些类型参数在类的定义中作为占位符,用于指定实际类型。
- 泛型类的定义语法
class 类名称 <泛型标识、泛型标识,...> {
private 泛型标识 变量名;
......
}
- 常用的泛型标识 T、E、K、V
代码示例
package 泛型;
//泛型:能够代表一切类型
public class Stack<A> {
//定义数组
private A[] arr;
private int i = -1;
public Stack(int size){
arr = (A[]) new Object[size]; //Object 是所有类的父类 把父类转换为子类
}
//添加数据
public void add(A value){
i++;
arr[i] = value;
}
//输出数据
public A get(){
return arr[i--];
}
}
4.泛型类的使用语法
- 使用语法
类名<具体的数据类型> 对象名 = new 类名<具体的数据类型>();
- java 1.7以后,后边的<>中具体的数据类型可以省略不写
类名<具体的数据类型> 对象名 = new 类名<>();
使用泛型时,可以在创建类的实例时指定具体的数据类型,或者作为方法的返回类型、参数类型等。
package 泛型;
public class Test {
public static void main(String[] args) {
Stack stack =new Stack(10);
stack.add(1);
stack.add(2);
stack.add(3);
stack.add(4);
System.out.println(stack.get());
System.out.println(stack.get());
System.out.println(stack.get());
System.out.println(stack.get());
Stack stack1 = new Stack(5);
stack1.add("保定");
stack1.add("上海");
stack1.add("北京");
System.out.println(stack1.get());
System.out.println(stack1.get());
System.out.println(stack1.get());
}
}
输出结果为:
4
3
2
1
北京
上海
保定
在这个例子中,A是一个类型参数,它代表了在创建Stack
类的实例时可以指定的任何类型。
5.常见的泛型标记
E | 常用于集合中表示元素类型。 |
T | 表示不确定的类型。 |
K | 常用于映射(Map)中表示键的类型。 |
V | 与K 一起使用,在映射中表示值的类型。 |
N | 有时用于表示数字类型。 |
R | 在泛型方法中,表示方法的返回类型,特别是当返回类型与输入参数类型不同时。 |
6.泛型类注意事项
- 泛型类,如果没有指定具体的数据类型,此时,操作类型是Object
- 泛型的类型参数只能是类类型,不能是基本数据类型
- 泛型类型在逻辑上可以看成是多个不同的类型,但实际上是相同类型
7.代码示例
年终抽奖器(可能会是奖金,也可能是奖品)
package Stack;
import java.util.ArrayList;
import java.util.Random;
public class ProductGetter <T>{
//奖金或者奖品
private T product;
//定义奖品,奖金池
ArrayList<T> arrayList = new ArrayList<>();
//添加奖品到奖品池
public void addProduct(T t){
arrayList.add(t);
}
//定义一个随机数,用来抽选奖品
Random random = new Random();
//抽奖
public T getProduct(){
product = arrayList.get(random.nextInt(arrayList.size()));
return product;
}
}
package Stack;
public class Test {
public static void main(String[] args) {
ProductGetter<String> stringProductGetter = new ProductGetter<>();
String[] strPro = {"苹果手机","华为手机","扫地机器人","咖啡机"};
//将奖品放入奖金池
for (int i = 0; i < strPro.length; i++) {
stringProductGetter.addProduct(strPro[i]);
}
String product = stringProductGetter.getProduct();
System.out.println("恭喜你抽中了:"+product);
System.out.println("****************************************");
ProductGetter<Integer> IntegerProductGetter = new ProductGetter<>();
Integer[] intPro = {100,1000,10000,20000};
//将奖品放入奖金池
for (int i = 0; i < intPro.length; i++) {
IntegerProductGetter.addProduct(intPro[i]);
}
Integer product1 = IntegerProductGetter.getProduct();
System.out.println("恭喜你获得了:"+product1+"元");
}
}
总结
泛型是Java等编程语言中一种非常重要的特性,它通过提供类型参数化的方式,提高了代码的复用性、类型安全性和性能,同时增强了代码的可读性和可维护性。在设计和编写软件时,合理使用泛型可以带来诸多好处。