【简化代码】 Java 泛型 提升抽象能力实际应用

Java 泛型 提升抽象能力

看完这篇文章,你将获取到 更简单复用的代码 更强的抽象能力 。

基础知识

为什么使用泛型(使用场景)

1.使程序员能够实现通用算法。

2.在编译时进行更强的类型检查,提高代码的安全性。

泛型类

一个泛型类的定义与格式如下:

类名<T1, T2, …, Tn> { /* … */ }

/**
 * Generic version of the Box class.
 * @param <T> the type of the value being boxed
 */
public class Box<T> {
    // T stands for "Type"
    private T t;

    public void set(T t) { this.t = t; }
    public T get() { return t; }
}

//实例化
Box<Integer> integerBox = new Box<>();

其中T是可以是您指定的任何非原始类型:任何类类型、任何接口类型、任何数组类型,甚至是另一个类型变量。

在Java中这些类型命名的约定如下:
最常用的类型参数名称是:

E - 元素(被 Java 集合框架广泛使用)
K - 键
N - 数字
T - 类型
V - 值
S、U、V 等 - 第 2、第 3、第 4 种类型

泛型接口

//泛型接口
public interface Pair<K, V> {
    public K getKey();
    public V getValue();
}

泛型方法

静态泛型方法 非静态泛型方法
public class Util {
	//静态泛型方法
    public static <K, V> boolean compare(Pair<K, V> p1, Pair<K, V> p2) {
        return p1.getKey().equals(p2.getKey()) &&
               p1.getValue().equals(p2.getValue());
    }
}

//实现泛型接口
public class OrderedPair<K, V> implements Pair<K, V> {

    private K key;
    private V value;
   
    //非静态泛型方法
    public OrderedPair(K key, V value) {
	this.key = key;
	this.value = value;
    }

    public K getKey()	{ return key; }
    public V getValue() { return value; }
}

//实例化
OrderedPair<String, Integer> p1 = new OrderedPair<>("Even", 8);
OrderedPair<String, String>  p2 = new OrderedPair<>("hello", "world");

Pair<Integer, String> p1 = new Pair<>(1, "apple");
Pair<Integer, String> p2 = new Pair<>(2, "pear");
boolean same = Util.compare(p1, p2);

好了,以上就是泛型的基础使用方法。下面进入日常使用

有界类型参数

什么叫有界类型参数,就是将泛型定为有界的,分为上界和下界,来限制参数类型,增强类型检查和使用有界类型的特性

上界

格式如下 T extends 具体的类型或接口
extends在一般意义上用于表示“继承”(如在类中)或“实现”(如在接口中)。

public class Box<T> {

    private T t;          

    public void set(T t) {
        this.t = t;
    }

    public T get() {
        return t;
    }

	//这里泛型方法 就用了上界 表示U 是Number类及其子类
    public <U extends Number> void inspect(U u){
        System.out.println("T: " + t.getClass().getName());
        System.out.println("U: " + u.getClass().getName());
    }

    public static void main(String[] args) {
        Box<Integer> integerBox = new Box<Integer>();
        integerBox.set(new Integer(10));
        // error: 这里就编译不通过,因为是String。 体现泛型作用之一的:增强类型检查
        integerBox.inspect("some text"); 
    }
}

//泛型类 使用上界
public class NaturalNumber<T extends Integer> {

    private T n;

    public NaturalNumber(T n)  { this.n = n; }

    public boolean isEven() {
    //因为定义了上界,所以我们就可以使用上界Integer的特性:intValue方法
        return n.intValue() % 2 == 0;
    }
}

下界

格式如下 ? super A
下限通配符将未知类型限制为特定类型或该类型的超类型。

假设您要编写一个将Integer对象放入列表的方法。为了最大限度地提高灵活性,您希望该方法适用于List<Integer>List<Number>List<Object> — 任何可以保存Integer值的东西。

要编写上的列表工程方法整和的超类型整数,如整型,数量和 对象,此时就需要使用下界。
因为List<Integer>只匹配一个Integer类型的列表,而List<? super Integer匹配一个Integer超类型的任何类型的列表。
public static void addNumbers(List<? super Integer> list) { 
    for (int i = 1; i <= 10; i++) { 
        list.add(i); } 
    } 
}

实际运用

我们使用枚举的时候,有时经常要根据枚举的code值来获取整个枚举,从而获取这个枚举其他属性。
一般我们都是在这个枚举中遍历枚举,然后根据code比较返回整个枚举。若有多个枚举就需要重复写类似逻辑。这里我们用泛型来抽象一下写法,减少代码量不需要每个枚举都写一遍

/**
 * @className: EnumBase
 * @description: 枚举接口抽象
 * @author: xk
 * @date: 2021/6/8 10:34
 **/
public interface EnumBase <T>{
    T getCode();

    String getMessage();

	/**
     * xk:根据code值判断是否在该枚举中
     *
     * @param enums
     * @param code
     * @return
     */
    static <T> boolean isExistBycode(EnumBase[] enums, T code) {
        if (code == null) {
            return false;
        }
        for (EnumBase e : enums) {
            if (code.equals(e.getCode())) {
                return true;
            }
        }
        return false;
    }
    
    /**
     * @param: enums 实现EnumBase的枚举值集合
     * @param: code 枚举code
     * @description: 通过枚举code 获取对应的枚举实体
     * @return: T  枚举实体
     * @author: xk
     * @date: 2021/6/29 20:36
     */
    static <T extends EnumBase, R> T getEnumByCode(T[] enums, R code) {
        for (T e : enums) {
            if (Objects.equals(code, e.getCode())) {
                return e;
            }
        }
        return null;
    }

}


enum StepInfoStatusEnum implements EnumBase<Integer> {
    init(0, "未开始"),
    success(1, "成功"),
    fail(2, "失败")

    Integer code

    String message

    StepInfoStatusEnum(Integer code, String message) {
        this.code = code
        this.message = message
    }

    @Override
    Integer getCode() {
        return this.code
    }

    @Override
    String getMessage() {
        return this.message
    }
}

//最后使用
StepInfoStatusEnum stepInfoStatusEnum  = EnumBase.getEnumByCode(StepInfoStatusEnum.values(),0)

最后附上Oracle官方教程地址:https://docs.oracle.com/javase/tutorial/java/generics/index.html

多总结,多学习

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值