Spec-Zone .ru
спецификации, руководства, описания, API
След: Изучение Языка Java
Урок: (Обновленные) Обобщения
Домашняя страница > Изучение Языка Java > (Обновленные) обобщения

Ответьте на Вопросы и Упражнения: Обобщения

  1. Запишите универсальный метод, чтобы считать число элементов в наборе, у которых есть определенное свойство (например, нечетные целые числа, простые числа, палиндромы).

    Ответ:
    public final class Algorithm {
        public static <T> int countIf(Collection<T> c, UnaryPredicate<T> p) {
    
            int count = 0;
            for (T elem : c)
                if (p.test(elem))
                    ++count;
            return count;
        }
    }
    
    где универсальный интерфейс UnaryPredicate определяется следующим образом:
    public interface UnaryPredicate<T> {
        public boolean test(T obj);
    }
    
    Например, следующая программа считает число нечетных целых чисел в целочисленном списке:
    import java.util.*;
    
    class OddPredicate implements UnaryPredicate<Integer> {
        public boolean test(Integer i) { return i % 2 != 0; }
    }
    
    public class Test {
        public static void main(String[] args) {
            Collection<Integer> ci = Arrays.asList(1, 2, 3, 4);
            int count = Algorithm.countIf(ci, new OddPredicate());
            System.out.println("Number of odd integers = " + count);
        }
    }
    
    Печатные издания программы:
    Number of odd integers = 2
    
  2. Следующий class скомпилирует? В противном случае, почему?
    public final class Algorithm {
        public static T max(T x, T y) {
            return x > y ? x : y;
        }
    }
    
    Ответ: Нет. Большее чем (>) оператор применяется только к примитивным числовым типам.

  3. Запишите универсальный метод, чтобы обмениваться позициями двух различных элементов в массиве.

    Ответ:
    public final class Algorithm {
        public static <T> void swap(T[] a, int i, int j) {
            T temp = a[i];
            a[i] = a[j];
            a[j] = temp;
        }
    }
    
  4. Если компилятор стирает все параметры типа во время компиляции, почему следует использовать обобщения?

    Ответ: следует использовать обобщения потому что:
    • Компилятор Java осуществляет более трудный тип, проверяет универсальный код во время компиляции.
    • Программирование поддержки обобщений вводит как параметры.
    • Обобщения позволяют Вам реализовать универсальные алгоритмы.


  5. Во что преобразовывается следующий class после стирания типа?
    public class Pair<K, V> {
    
        public Pair(K key, V value) {
            this.key = key;
            this.value = value;
        }
    
        public K getKey(); { return key; }
        public V getValue(); { return value; }
    
        public void setKey(K key)     { this.key = key; }
        public void setValue(V value) { this.value = value; }
    
        private K key;
        private V value;
    }
    
    Ответ:
    public class Pair {
    
        public Pair(Object key, Object value) {
            this.key = key;
            this.value = value;
        }
    
        public Object getKey()   { return key; }
        public Object getValue() { return value; }
    
        public void setKey(Object key)     { this.key = key; }
        public void setValue(Object value) { this.value = value; }
    
        private Object key;
        private Object value;
    }
    
  6. Во что преобразовывается следующий метод после стирания типа?
    public static <T extends Comparable<T>>
        int findFirstGreaterThan(T[] at, T elem) {
        // ...
    }
    
    Ответ:
    public static Comparable
        int findFirstGreaterThan(Comparable[] at, Comparable elem) {
        // ...
        }
    
  7. Следующий метод скомпилирует? В противном случае, почему?
    public static void print(List<? super Number> list) {
        for (Number n : list)
            System.out.print(n + " ");
        System.out.println();
    }
    
    Ответ: Да.

  8. Запишите универсальный метод, чтобы счесть максимальный элемент в диапазоне [begin, end) списка.

    Ответ:
    import java.util.*;
    
    public final class Algorithm {
        public static <T extends Object & Comparable<? super T>>
            T max(List<? extends T> list, int begin, int end) {
    
            T maxElem = list.get(begin);
    
            for (++begin; begin < end; ++begin)
                if (maxElem.compareTo(list.get(begin)) < 0)
                    maxElem = list.get(begin);
            return maxElem;
        }
    }
    
  9. Следующий class скомпилирует? В противном случае, почему?
    public class Singleton<T> {
    
        public static T getInstance() {
            if (instance == null)
                instance = new Singleton<T>();
    
            return instance;
        }
    
        private static T instance = null;
    }
    
    Ответ: Нет. Невозможно создать статическое поле параметра типа T.

  10. Учитывая следующие классы:
    class Shape { /* ... */ }
    class Circle extends Shape { /* ... */ }
    class Rectangle extends Shape { /* ... */ }
    
    class Node<T> { /* ... */ }
    
    Следующее кодирует компиляцию? В противном случае, почему?
    Node<Circle> nc = new Node<>();
    Node<Shape>  ns = nc;
    
    Ответ: Нет. Поскольку Node<Circle> не является подтипом Node<Shape>.

  11. Рассмотрите этот class:
    class Node<T> implements Comparable<T> {
        public int compareTo(T obj) { /* ... */ }
        // ...
    }
    
    Следующее кодирует компиляцию? В противном случае, почему?

    Ответ: Да.
    Node<String> node = new Node<>();
    Comparable<String> comp = node;
    
  12. Как Вы вызываете следующий метод, чтобы найти первое целое число в списке, который является относительно главным к списку указанных целых чисел?
    public static <T>
        int findFirst(List<T> list, int begin, int end, UnaryPredicate<T> p)
    
    Отметьте, что два целых числа a и b являются относительно главными, если НОД (a, b) = 1, где НОД короток для наибольшего общего делителя.

    Ответ:
    import java.util.*;
    
    public final class Algorithm {
    
        public static <T>
            int findFirst(List<T> list, int begin, int end, UnaryPredicate<T> p) {
    
            for (; begin < end; ++begin)
                if (p.test(list.get(begin)))
                    return begin;
            return -1;
        }
    
        // x > 0 and y > 0
        public static int gcd(int x, int y) {
            for (int r; (r = x % y) != 0; x = y, y = r) { }
                return y;
        }
    }
    
    Универсальный интерфейс UnaryPredicate определяется следующим образом:
    public interface UnaryPredicate<T> {
        public boolean test(T obj);
    }
    
    Следующая программа тестирует метод findFirst:
    import java.util.*;
    
    class RelativelyPrimePredicate implements UnaryPredicate<Integer> {
        public RelativelyPrimePredicate(Collection<Integer> c) {
            this.c = c;
        }
    
        public boolean test(Integer x) {
            for (Integer i : c)
                if (Algorithm.gcd(x, i) != 1)
                    return false;
    
            return c.size() > 0;
        }
    
        private Collection<Integer> c;
    }
    
    public class Test {
        public static void main(String[] args) throws Exception {
    
            List<Integer> li = Arrays.asList(3, 4, 6, 8, 11, 15, 28, 32);
            Collection<Integer> c = Arrays.asList(7, 18, 19, 25);
            UnaryPredicate<Integer> p = new RelativelyPrimePredicate(c);
    
            int i = ALgorithm.findFirst(li, 0, li.size(), p);
    
            if (i != -1) {
                System.out.print(li.get(i) + " is relatively prime to ");
                for (Integer k : c)
                    System.out.print(k + " ");
                System.out.println();
            }
        }
    }
    
    Печатные издания программы:
    11 is relatively prime to 7 18 19 25
    
«ПредыдущийTOC

Проблемы с примерами? Попытайтесь Компилировать и Выполнить Примеры: FAQ.
Жалобы? Поздравление? Предложения? Дайте нам свою обратную связь
.

Предыдущая страница: Вопросы и Упражнения: Обобщения