public class Pair<T>{
private T first;
private T second;
public Pair(){
first = null;
second = null;}
public Pair(T first, T second){
this.first = first;
this.second = second;}
public T getFirst(){return first;}
public T getSecond(){return second;}
public voidsetFirst(T newValue){
first = newValue;}
public voidsetSecond(T newValue){
second = newValue;}}
Pair<String> nXX;
class ArrayAlg
{
public static<T> T getMiddle(T... a){return a[a.length /2];}}
String middle = ArrayAlg.<String>getMiddle("John","Q","Public");// 编译器可从参数推断时,<String>可以省略
String middle = ArrayAlg.getMiddle("John","Q","Public");
- 类型变量的限定
class ArrayAlg
{
public static<T> T min(T[] a){if(a == null || a.length ==0)return null;
T smallest = a[0];for(int i =1; i < a.length; i++){if(smallest.compareTo(a[i])>0){
smallest = a[i];}return smallest;}}}
public static<T extends Comparable> T min(T[] a)...
T extends Comparable & Serializable
package pair2;
import java.time.*;
public class PairTest2
{
public staticvoidmain(String[] args){
LocalDate[] birthdays ={
LocalDate.of(1906,12,9),
LocalDate.of(1815,12,10),
LocalDate.of(1903,12,3),
LocalDate.of(1910,6,22),};
Pair<LocalDate> mm = ArrayAlg.minmax(birthdays);}}
class ArrayAlg
{
public static<T extends Comparable> Pair<T>minmax(T[] a){if(a == null || a.length ==0)return null;
T min = a[0];
T max = a[0];for(int i =1; i < a.length; i++){if(min.compareTo(a[i])>0) min = a[i];if(max.compareTo(a[i])<0) max = a[i];}return new Pair<>(min, max);}}
// Pair<T>的原始类型如下所示
public class Pair
{
private Object first;
private Object second;
public Pair(Object first, Object second){
this.first = first;
this.second = second;}
public Object getFirst(){return first;}
public Object getSecond(){return second;}
public voidsetFirst(Object newValue){
first = newValue;}
public voidsetSecond(Object newValue){
second = newValue;}}
// 不能将Pair<Manager>传递给这个方法。解决方法很简单,可使用一个通配符类型
public staticvoidprintBuddies(Pair<Employee> p){
Employee first = p.getFirst();
Employee second = p.getSecond();
System.out.println(first.getName()+" and "+ second.getName()+" are buddies.");// ok now
public staticvoidprintBuddies(Pair<? extends Employee> p){...}// new Pair(...)
var managerBuddies = new Pair<Manager>(ceo, cfo);// Pair<? ...> xxx = new Pair(...) ok
Pair<? extends Employee> wildcardBuddies = managerBuddies;// lowlyEmployee必须是Employee派生类
wildcardBuddies.setFirst(lowlyEmployee);// getXXX 返回结果为Employee派生类,但存储到Employee可以
- 通配符的超类型限定
可以指定一个超类型限定
// setXXX 设置超类型,可以。设置派生类型 也可以。// getXXX 返回超类型。要用派生类型接收结果,不可以。// 归根到底是,可以用 基础类型接收派生类型,不可以用派生类型接收基础类型。? super Manager
public staticvoidminmaxBonus(Manager[] a, Pair<? super Manager> result){if(a.length ==0)return;
Manager min = a[0];
Manager max = a[0];for(int i =1; i < a.length; i++){if(min.getBonus()> a[i].getBonus()) min = a[i];if(max.getBonus()< a[i].getBonus()) max = a[i];}
result.setFirst(min);
result.setSecond(max);}
public static boolean hasNulls(Pair<?> p){return p.getFirst()== null || p.getSecond()== null;}// 通过将hasNull转换成泛型方法,可避免使用通配符类型
public static<T> boolean hasNulls(Pair<T> p)// 但是,带有通配符的版本可读性更好
- 通配符捕获
通配符不是类型变量,不能在编写代码中使用"?"作为一种类型。
public static<T>voidswapHelper(Pair<T> p){
T t = p.getFirst();
p.setFirst(p.getSecond());
p.setSecond(t);}
public staticvoidswap(Pair<?> p){// 用泛型T捕获通配符?swapHelper(p);}
public staticvoidmaxminBonus(Manager[] a, Pair<? super Manager> result){minmaxBonus(a, result);
PairAlg.swapHelper(result);}
public static<T> Pair<T>makePair(Class<T> c) throws InstantiationException,
IllegalAccessException
{return new Pair<>(c.newInstance(), c.newInstance());}
- 定义简单泛型类public class Pair<T>{ private T first; private T second; public Pair() { first = null; second = null; } public Pair(T first, T second) { this.first = first; this.second = second; } public T getFirst() { return firs