泛型(Generics)是Java编程语言中的一项重要特性,它使得编写的代码能够更具灵活性和类型安全性。
一、什么是泛型
泛型允许在定义类、接口和方法时使用类型参数,从而使得代码可以处理不同类型的对象,而无需编写多个重复的代码。泛型的主要目的是在编译时确保类型安全,并减少类型转换带来的错误。
1、泛型的定义
泛型类是在类名后面使用尖括号<>
来指定一个或多个类型参数的类。类型参数通常用大写字母表示,如T
、E
、K
、V
等。
public class Box<T> {
private T value;
public void setValue(T value) {
this.value = value;
}
public T getValue() {
return value;
}
}
在上面的例子中,Box
类是一个泛型类,它可以存储任意类型的对象,具体的类型在实例化时指定。
Box<Integer> integerBox = new Box<>();
integerBox.setValue(10);
Integer intValue = integerBox.getValue();
Box<String> stringBox = new Box<>();
stringBox.setValue("Hello");
String strValue = stringBox.getValue();
2、泛型方法的定义
泛型方法是在方法返回类型前面使用类型参数。泛型方法可以在泛型类中定义,也可以在普通类中定义。
public class GenericMethodExample {
public <T> void printArray(T[] array) {
for (T element : array) {
System.out.println(element);
}
}
public static void main(String[] args) {
GenericMethodExample example = new GenericMethodExample();
Integer[] intArray = {1, 2, 3, 4, 5};
example.printArray(intArray);
String[] strArray = {"A", "B", "C"};
example.printArray(strArray);
}
}
在这个例子中,printArray
方法是一个泛型方法,它可以打印任意类型的数组。
二、引例--Stack类
1、Stack类
用Java实现栈结构(数据先进后出)
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--];
}
}
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());
}
}
输出结果:
4
3
2
1
现在我们可以存储1234这样的数值型的数据,但是我们是否可以存储浮点类型或字符串类型的数据吗?是不可以的
解决后的栈:
public class StringStack {
private String[] arr;
private int i = -1;
public StringStack(int size){
arr = new String[size];
}
//添加数据
public void add(String value){
i++;
arr[i]= value;
}
//输出数据
public String get(){
return arr[i--];
}
}
public class Test {
public static void main(String[] args) {
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());
}
}
输出结果:
保定
上海
北京
我们现在想要存储float或者布尔类型的数据都要重新写一个"**Stack.java",这样效率很低下。但是用泛型可以做到
2、改进后的Stack类
public class Stack<T> {
//定义数组
private T[] arr;
private int i = -1;
public Stack(int size){
arr = (T[])new Object[size]; //object类是所有类型的子类,父类转成子类要强转
}
//添加数据
public void add(T value){
i++;
arr[i]= value;
}
//输出数据
public T get(){
return arr[i--];
}
}
public class Test {
public static void main(String[] args) {
System.setOut(new PrintStream(System.out, true, StandardCharsets.UTF_8));
Stack stack = new Stack(10);
stack.add(1);
stack.add("北京");
stack.add(1==1);
stack.add(10.0);
System.out.println(stack.get());
System.out.println(stack.get());
System.out.println(stack.get());
System.out.println(stack.get());
}
}
输出结果:
10.0
true
北京
1
三、经典题
年终抽奖器(可能会是奖金,也可能是奖品)
import java.util.ArrayList;
import java.util.Random;
/**
* 抽奖器
* @param <T>
*/
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;
}
}
import java.util.Arrays;
public class Test_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+"元");
}
}