Java 泛型三大使用场景

Java 泛型三大使用场景

1. 泛型类

最常见的泛型类就属容器类了。这里我自己实现了一个简单的 Container,非常简单…非常非常…
以下是代码

class Container1 {
    private String key;
    private String value;

    public Container1(String key, String value) {
        this.key = key;
        this.value = value;
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return "Container1 [key=" + key + ", value=" + value + "]";
    }

}

所有的 key 和 value 都是字符串。类型被写死。这种集合类的可用场景就十分局限。
下面使用泛型来重新定义这个类

class Container2<K, V> {
    K key;
    V value;

    public Container2(K k, V v) {
        this.key = k;
        this.value = v;
    }

    public K getKey() {
        return key;
    }

    public void setKey(K key) {
        this.key = key;
    }

    public V getValue() {
        return value;
    }

    public void setValue(V value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return "Container2 [key=" + key + ", value=" + value + "]";
    }

}

看上去棒极了!
在编译期间是不知道 K 和 V 的具体类型的,只有在运行时才会根据类型来具体分配内存。灵活性极高!

2. 泛型接口

最常看见的泛型接口是 List, 它是这样定义的
public interface List<E> extends Collection<E>
我也学习它,定义一个我的泛型接口

interface MyIter<T> {
    T next();
}

接下来给接口定义实现

class MyIterImpl implements MyIter<String> {
    @Override
    public String next() {
        String str = String.valueOf("str:"+System.currentTimeMillis());
        return str;
    }
}

class MyIterImpl2 implements MyIter<Long> {
    @Override
    public Long next() {
        return System.currentTimeMillis();
    }
}

可见,MyIterImpl生成的都是String类型,而MyIterImpl2生成的都是Long类型,这是在定义时就定好的。
我们来使用一下!
result1

3. 泛型方法

定义泛型方法,有一套对应的语法
<Class> 返回值 方法名(泛型变量) // 描述的不是很清楚

我也试着定义了一个泛型方法。

public static <T> void print(T t) {
    System.out.println(t);
}

可见,方法的参数彻底的泛型化了。编译器自动帮我们做了类型推导。这样在定义方法的时候不必考虑参数的类型,大大增加了灵活性。
让我们尽情使用他吧!
result2

4. 练习

使用泛型,定义一个自己的排序方法

1. 思路

  1. 排序方式:冒泡排序
  2. 泛型类型:所有实现了Comparable的类
  3. 参数:不定参数
  4. 返回值:排序完成的结果数组

2. 实现方法

@SafeVarargs
public static <T extends Comparable<T>> T[] sort(T ... t) {
    if(t == null) {
        return null;
    }
    int length = t.length;
    for(int i=0;i<length-1;i++) {
        for(int j=i+1;j<length;j++) {
            if(t[i].compareTo(t[j]) > 0) {
                T k = t[i];
                t[i] = t[j];
                t[j] = k;
            }
        }
    }
    return t;
}

3. 验证

result3

5. 结尾

泛型应该算是 Java 里一个比较重要的点。
对于泛型方法,我很赞同查到的一句话

无论何时,只要你能做到,就应该尽量使用泛型方法

6. 感谢