📜  Java45 泛型(1)

📅  最后修改于: 2023-12-03 15:31:35.382000             🧑  作者: Mango

Java45 泛型

Java 泛型是 Java SE 5 中引入的一项新特性,它提供了编写更加通用和类型安全的代码的方式。Java 泛型可以让我们编写与特定类型无关的代码,这使得代码更加灵活和易于重用。

泛型的定义和使用

Java 泛型是一种抽象的类型或方法,它定义了一个可以应用于多个不同类型的类型或方法。Java 泛型使用尖括号 < > 来指定类型参数。例如,下面的代码定义了一个泛型类 List<T>

public class List<T> {
  private T[] array;
  
  public List(T[] array) {
    this.array = array;
  }
  
  public T get(int index) {
    return array[index];
  }
  
  public void set(int index, T value) {
    array[index] = value;
  }
}

在上面的代码中,<T> 表示 List 类是一个泛型类,并且 T 是一个类型参数。List<T> 类里的方法可以使用 T 类型参数来定义方法参数类型、返回值类型和局部变量类型。例如,getset 方法的返回值和参数类型都是 T 类型。

我们可以通过以下方式来使用 List 泛型类:

Integer[] numbers = { 1, 2, 3 };
List<Integer> list = new List<>(numbers);
System.out.println(list.get(1)); // Output: 2
list.set(2, 4);
System.out.println(list.get(2)); // Output: 4

在上面的代码中,我们创建了一个包含整数的数组 numbers,然后使用它来初始化 List<Integer> 类型的变量 list。我们可以通过调用 getset 方法来访问和更新 list 列表中的元素。由于 List 泛型类是类型安全的,我们不能将一个不是 Integer 类型的值赋值给 list 列表中的元素。

泛型类、接口和方法

Java 泛型不仅可以用于类,还可以用于接口和方法。以下是一些例子:

泛型类
public class Pair<T, U> {
  private T first;
  private U second;
  
  public Pair(T first, U second) {
    this.first = first;
    this.second = second;
  }
  
  public T getFirst() {
    return first;
  }
  
  public U getSecond() {
    return second;
  }
}

在上面的代码中,Pair<T, U> 是一个泛型类,可以包含两个不同类型的元素。

泛型接口
public interface Comparator<T> {
  public int compare(T o1, T o2);
}

在上面的代码中,Comparator<T> 是一个泛型接口,定义了一个用于比较两个对象的抽象方法。

泛型方法
public static <T> T max(T[] array) {
  T max = array[0];
  for (int i = 1; i < array.length; i++) {
    if (array[i].compareTo(max) > 0) {
      max = array[i];
    }
  }
  return max;
}

在上面的代码中,<T> 表示该方法是一个泛型方法,并且 T 是一个类型参数。该方法使用 T 类型参数来定义方法参数类型和返回值类型。

通配符和边界

Java 泛型允许使用通配符 ? 来表示未知的类型。例如:

List<?> list = new ArrayList<>();

在上面的代码中,List<?> 表示一个未知类型的列表。由于我们不知道列表中的元素类型,我们不能像访问正常列表一样来访问它们的元素。

Java 泛型也允许使用边界来限制泛型的类型参数。例如:

public static <T extends Comparable<T>> T max(T[] array) {
  T max = array[0];
  for (int i = 1; i < array.length; i++) {
    if (array[i].compareTo(max) > 0) {
      max = array[i];
    }
  }
  return max;
}

在上面的代码中,<T extends Comparable<T>> 表示 T 类型参数必须是 Comparable<T> 接口的子类型。这使得我们可以在方法中使用 compareTo 方法来比较两个对象。

JDK 中的泛型示例

JDK 中有很多使用泛型的类和接口,例如 java.util.Listjava.util.Mapjava.util.Setjava.util.Comparator 等。以下是一些使用泛型的例子:

List
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
System.out.println(list); // Output: [1, 2, 3]
Map
Map<String, String> map = new HashMap<>();
map.put("key1", "value1");
map.put("key2", "value2");
System.out.println(map); // Output: {key1=value1, key2=value2}
Set
Set<Integer> set = new HashSet<>();
set.add(1);
set.add(2);
set.add(3);
System.out.println(set); // Output: [1, 2, 3]
Comparator
List<String> list = Arrays.asList("red", "green", "blue");
Collections.sort(list, new Comparator<String>() {
  public int compare(String s1, String s2) {
    return s1.length() - s2.length();
  }
});
System.out.println(list); // Output: [red, blue, green]

在上面的代码中,我们使用 Collections.sort 方法来对字符串列表进行排序。我们传递了一个实现 Comparator<String> 接口的匿名类作为第二个参数,该匿名类使用字符串长度来比较两个字符串。

总结

Java 泛型是一个强大的特性,它可以让我们编写更加通用和类型安全的代码。使用 Java 泛型可以使代码更加灵活和易于重用,同时也可以使我们写出更清晰、更可读的代码。通过掌握 Java 泛型的知识,我们可以更好地为开发任务服务,并在我们的应用程序中实现更强大的功能。