На этом шаге мы рассмотрим создание обобщенного класса
Обобщенным называется класс с одной или более переменной типа. В качестве примера рассмотрим класс Pair. Ниже приведен данный класс:
public class Pair<T> { private T first; private T second; public Pair() { this.first = null; this.second = null; } public Pair(T first, T second) { this.first = first; this.second = second; } public T getFirst() { return first; } public void setFirst(T first) { this.first = first; } public T getSecond() { return second; } public void setSecond(T second) { this.second = second; } }
В классе Pair вводится переменная типа T, заключенная в угловые скобки (<>) после имени самого класса. У обобщенного класса может быть больше одной переменной типа. Например, класс Pair можно было бы определить с разными типами для первого и второго поля:
public class Pair<U, V> {...}
Переменные типа используются повсюду в определении класса для обозначения типов, возвращаемых методами, а также типов полей и локальных переменных.
В именах переменных принято употреблять заглавные буквы и стремиться к их краткости. Например, в библиотеке Java буквой E обозначается тип элемента коллекции, буквами K и V - тип ключей и значений в таблице, а буквой T - вообще любой тип.
Экземпляр обобщенного типа создается путем подстановки имени типа вместо переменной типа следующим образом:
Pair<String>
Результат такой подстановки следует рассматривать как обычный класс с конструкторами:
Pair<String>(); Pair<String>(String, String);
и методами
String getFirst(); String getSecond(); void setFirst(String value); void setSecond(String value);
Иными словами, обобщенный класс действует как фабрика обычных классов. Приведем ниже пример использования класса Pair для поиска минимального и максимального элемента в массиве.
/** * <p>Класс для тестирования программы</p> * */ public class PairTest { public static void main(String[] args) { String[] words = {"name1", "b", "name3", "c", "name2", "a"}; Pairmm = ArrayAlg.minmax(words); System.out.println("min = " + mm.getFirst()); System.out.println("max = " + mm.getSecond()); } } /** * <p>Класс, который представляет из себя пару обобщенных значений</p> * */ class Pair<T> { private T first; private T second; /** * <p>Конструктор по умолчанию</p> * */ public Pair() { this.first = null; this.second = null; } /** * <p>Конструктор, который принимает два значения</p> * @param first Первое значение * @param second Второе значение * */ public Pair(T first, T second) { this.first = first; this.second = second; } /** * <p>Функция для получения первого значения</p> * @return Первое значение * */ public T getFirst() { return first; } /** * <p>Функция для изменения первого значения</p> * @param first Первое значение * */ public void setFirst(T first) { this.first = first; } /** * <p>Функция для получения второго значения</p> * @return Второе значение * */ public T getSecond() { return second; } /** * <p>Функция для изменения второго значения</p> * @param second Второе значение * */ public void setSecond(T second) { this.second = second; } } /** * <p>Класс для поиска минимального и максимального элемента в массиве</p> * */ class ArrayAlg { /** * <p>Функция для поиска минимального и максимального элемента в массиве</p> * @param a Массив строк. * @return Минимальное и максимальное значение, упакованные в пару * */ public static Pair<String> minmax(String[] a) { if (a == null || a.length == 0) { return null; } String min = a[0]; String 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); } }
Проект можно взять здесь
Рис. 1. Вывод программы
На следующем шаге мы рассмотрим обобщенные методы