625 lines
35 KiB
TeX
625 lines
35 KiB
TeX
\documentclass[j-spec.tex]{subfiles}
|
||
\usepackage{spreadtab}
|
||
|
||
\begin{document}
|
||
\section{Семинар: Обобщения}
|
||
\subsection{Инструментарий}
|
||
\begin{itemize}
|
||
\item \href{https://docs.google.com/presentation/d/1rWHGQBITRElvyKFEjwe8dOinDbAV2ZW18tAK1FXU48U/edit?usp=share_link}{Презентация} для преподавателя, ведущего семинар;
|
||
\item \href{https://drive.google.com/file/d/1LWyE8aEy4-1gsognqhXIXwDcoLviVge4/view}{Фон} GeekBrains для проведения семинара в Zoom;
|
||
\item JDK любая 11 версии и выше;
|
||
\item \href{https://www.jetbrains.com/idea/download}{IntelliJ IDEA Community Edition} для практики и примеров используется IDEA.
|
||
\end{itemize}
|
||
|
||
\subsection{Цели семинара}
|
||
\begin{itemize}
|
||
\item Практика создания простых обобщений;
|
||
\item Создание собственного обобщённого контейнера с описанием базовых алгоритмов (введение в коллекции);
|
||
\item Изучение поведения объекта итератора;
|
||
\item Закрепление понимания механизмов работы коллекций.
|
||
\end{itemize}
|
||
|
||
\subsection{План-содержание}
|
||
\noindent
|
||
\begin{spreadtab}{{longtable}{|p{37mm}|l|l|p{90mm}|}}
|
||
\hline
|
||
@ Что происходит & @ Время & @ Слайды & @ Описание \\
|
||
\hline
|
||
\endhead
|
||
@ Организационный момент & 5 tag(beg) & @ 1-5 & @ Преподаватель ожидает студентов, поддерживает активность и коммуникацию в чате, озвучивает цели и планы на семинар. Важно упомянуть, что выполнение домашних заданий с лекции является, фактически, подготовкой к семинару \\
|
||
\hline
|
||
@ Quiz & 5 & @ 6-18 & @ Преподаватель задаёт вопросы викторины, через 30 секунд демонстрирует слайд-подсказку и ожидает ответов (по минуте на ответ) \\
|
||
\hline
|
||
@ Рассмотрение ДЗ лекции & 10 & @ 19-23 & @ Преподаватель демонстрирует свой вариант решения домашнего задания с лекции, возможно, по предварительному опросу, демонстрирует и разбирает вариант решения одного из студентов \\
|
||
\hline
|
||
@ Вопросы и ответы & 10 & @ 24 & @ Преподаватель ожидает вопросов по теме прошедшей лекции, викторины и продемонстрированной работы \\
|
||
\hline
|
||
@ Задание 1 & 10 & @ 25-27 & @ Формирование навыков базовой работы с обобщениями \\
|
||
\hline
|
||
@ Задание 2 & 20 & @ 28-30 & @ Практика написания обобщённого кода с дополнительным описанием алгоритмов манипулирования данными \\
|
||
\hline
|
||
@ Перерыв (если нужен) & 5 & @ 31 & @ Преподаватель предлагает студентам перерыв на 5 минут (студенты голосуют) \\
|
||
\hline
|
||
@ Задание 3 & 20 & @ 32-34 & @ Изучение поведения итератора для понимания механизмов его действия и необходимости его использования в работе \\
|
||
\hline
|
||
@ Задание 4 & 20 & @ 35-38 & @ Закрепление понимания механизмов работы коллекций (в том числе с применением итераторов) \\
|
||
\hline
|
||
@ Домашнее задание & 5 & @ 39-40 & @ Объясните домашнее задание, подведите итоги урока \\
|
||
\hline
|
||
@ Рефлексия & 10 tag(end) & @ 41-42 & @ Преподаватель запрашивает обратную связь \\
|
||
\hline
|
||
@ Длительность & sum(cell(beg):cell(end)) & & \\
|
||
\hline
|
||
\end{spreadtab}
|
||
|
||
\subsection{Подробности}
|
||
\subsubsection*{Организационный момент}
|
||
\begin{itemize}
|
||
\item \textbf{Цель этапа:} Позитивно начать урок, создать комфортную среду для обучения.
|
||
\item \textbf{Тайминг:} 3-5 минут.
|
||
\item \textbf{Действия преподавателя:}
|
||
\begin{itemize}
|
||
\item Запрашивает активность от аудитории в чате;
|
||
\item Презентует цели курса и семинара;
|
||
\item Презентует краткий план семинара и что студент научится делать.
|
||
\end{itemize}
|
||
\end{itemize}
|
||
|
||
\subsubsection*{Quiz}
|
||
\begin{itemize}
|
||
\item \textbf{Цель этапа:} Вовлечение аудитории в обратную связь.
|
||
\item \textbf{Тайминг:} 5--7 минут (4 вопроса, по минуте на ответ).
|
||
\item \textbf{Действия преподавателя:}
|
||
\begin{itemize}
|
||
\item Преподаватель задаёт вопросы викторины, представленные на слайдах презентации;
|
||
\item через 30 секунд демонстрирует слайд-подсказку и ожидает ответов.
|
||
\end{itemize}
|
||
\item \textbf{Вопросы и ответы:}
|
||
\begin{enumerate}
|
||
\item Какая основная цель использования Java generics? (1)
|
||
\begin{enumerate}
|
||
\item Упрощение программирования и повышение безопасности типов
|
||
\item Ускорение работы программы и сокращение объема кода
|
||
\item Позволяют работать с различными базами данных одновременно
|
||
\end{enumerate}
|
||
% Неверные ответы: b) и c) - generics не связаны с ускорением работы программы или работой с базами данных, их основная цель - добавить типовую безопасность и упростить программирование.
|
||
\item Что такое параметризованный класс в Java generics? (1)
|
||
\begin{enumerate}
|
||
\item Класс, который принимает параметр типа
|
||
\item Класс, который имеет только один параметр типа
|
||
\item Класс, который можно использовать только с определенным типом данных
|
||
\end{enumerate}
|
||
% Неверные ответы: b) и c) - параметризованный класс может иметь любое количество параметров типа и может быть использован с различными типами данных.
|
||
\item Какие ограничения можно использовать с wildcard в Java generics? (1)
|
||
\begin{enumerate}
|
||
\item extends и super
|
||
\item only
|
||
\item extends
|
||
\end{enumerate}
|
||
% Неверные ответы: b) и c) - в generics для ограничения типа используются ключевые слова extends и super, а не only или extends.
|
||
|
||
\item Можно ли создать экземпляр обобщенного типа в Java, внутри класса, описывающего этот тип? (2)
|
||
\begin{enumerate}
|
||
\item Да, это возможно
|
||
\item Нет, такое создание экземпляров обобщенных типов запрещено
|
||
\item Это зависит от контекста использования обобщенного типа
|
||
\end{enumerate}
|
||
% Неверные ответы: a) и c) - экземпляры обобщенных типов не могут быть созданы в Java из-за стирания типов, однако можно создать экземпляр обобщенного класса, указав конкретный тип данных.
|
||
\end{enumerate}
|
||
\end{itemize}
|
||
|
||
\subsubsection*{Рассмотрение ДЗ}
|
||
\begin{itemize}
|
||
\item \textbf{Цель этапа:} Пояснить не очевидные моменты в формулировке ДЗ с лекции, синхронизировать прочитанный на лекции материал к началу семинара.
|
||
\item \textbf{Тайминг:} 15-20 минут.
|
||
\item \textbf{Действия преподавателя:}
|
||
\begin{itemize}
|
||
\item Преподаватель демонстрирует свой вариант решения домашнего задания из лекции;
|
||
\item возможно, по предварительному опросу, демонстрирует и разбирает вариант решения одного из студентов.
|
||
\end{itemize}
|
||
\item \textbf{Домашнее задание из лекции:}
|
||
\begin{itemize}
|
||
\item Написать метод, который меняет два элемента массива местами (массив может быть любого ссылочного типа);
|
||
|
||
\textbf{Вариант решения}
|
||
|
||
Задание с подвохом, при решении необязательно было использовать дженерики, формулировка задания не ограничивает используемые в массиве типы, наоборот, явно проговаривается, что массив может быть любого типа.
|
||
\begin{lstlisting}[language=Java,style=JCodeStyle]
|
||
private static void swap(Object[] arr, int from, int to) {
|
||
Object temp = arr[from];
|
||
arr[from] = arr[to];
|
||
arr[to] = temp;
|
||
}
|
||
|
||
public static void main(String[] args) {
|
||
Object[] arr = {1, 2.0f, "hello"};
|
||
System.out.println(Arrays.toString(arr));
|
||
swap(arr, 0, 2);
|
||
System.out.println(Arrays.toString(arr));
|
||
}
|
||
\end{lstlisting}
|
||
|
||
\item Большая задача:
|
||
\begin{itemize}
|
||
\item Есть классы \code{Fruit} -> \code{Apple}, \code{Orange}; (больше не надо);
|
||
\item Класс \code{Box} в который можно складывать фрукты, коробки условно сортируются по типу фрукта, поэтому в одну коробку нельзя сложить и яблоки, и апельсины; Для хранения фруктов внутри коробки можете использовать \code{ArrayList};
|
||
\item Сделать метод \code{getWeight()} который высчитывает вес коробки, зная количество фруктов и вес одного фрукта(вес яблока -- \code{1.0f}, апельсина -- \code{1.5f}, не важно в каких единицах);
|
||
\item Внутри класса коробки сделать метод \code{compare()}, который позволяет сравнить текущую коробку с той, которую подадут в \code{compare()} в качестве параметра, \code{true} -- если их веса равны, \code{false} в противном случае (коробки с яблоками возможно сравнивать с коробками с апельсинами);
|
||
\item Написать метод, который позволяет пересыпать фрукты из текущей коробки в другую коробку (при этом, нельзя яблоки высыпать в коробку с апельсинами), соответственно, в текущей коробке фруктов не остается, а в другую перекидываются объекты, которые были в этой коробке.
|
||
\end{itemize}
|
||
|
||
\textbf{Вариант решения}
|
||
Создали фрукты с каким то разным весом, создали коробку, которая может вместить только фрукты. Надо фрукты там как то хранить, поэтому -- список. Соответственно при создании можем в нашу коробку какие то фрукты накидать. Соответственно метод, который будет уметь добавлять фрукты в коробку
|
||
\begin{lstlisting}[language=Java,style=JCodeStyle,caption={ }]
|
||
private interface Fruit { float getWeight(); }
|
||
private static class Apple implements Fruit {
|
||
static final float weight = 1.0f;
|
||
@Override public float getWeight() { return weight; }
|
||
}
|
||
private static class Orange implements Fruit {
|
||
static final float weight = 1.5f;
|
||
@Override public float getWeight() { return weight; }
|
||
}
|
||
public static class Box<T extends Fruit> {
|
||
private final List<T> container;
|
||
Box(T[] init) {
|
||
container = new ArrayList<>();
|
||
for (T f : init) { add(f); }
|
||
}
|
||
void add(T fruit) { container.add(fruit); }
|
||
void print() { System.out.println(getWeight()); }
|
||
}
|
||
\end{lstlisting}
|
||
|
||
Поскольку в коробке у нас могут быть только одно типа фрукты -- мы можем не перебирать каждый из них, а умножить вес одного на количество.
|
||
\begin{lstlisting}[language=Java,style=JCodeStyle,caption={ }]
|
||
float getWeight() {
|
||
return (container.isEmpty())
|
||
? 0
|
||
: container.get(0).getWeight() * container.size();
|
||
}
|
||
\end{lstlisting}
|
||
|
||
Можно было, по большому счёту, переопределить метод equals() или написать свой метод compare() который принимает вторую коробку и сравнивает вес. Сравнивать можно любые фрукты, значит в методе не подходит параметр типа \code{<T>}
|
||
\begin{lstlisting}[language=Java,style=JCodeStyle,caption={ }]
|
||
boolean compare(Box<?> with) {
|
||
return this.getWeight() - with.getWeight() < 0.0001;
|
||
}
|
||
\end{lstlisting}
|
||
|
||
Осталось только уметь пересыпать из одной коробки в другую не смешивая. На входе должна быть коробка того же типа, что и у объекта, и тут два пути, либо пересыпать всё из текущей коробки в другую, либо из другой в текущую, метод назван \code{transferTo()}, поэтому пересыпаться фрукты будут из текущей коробки. Возникает вопрос: если создаётся коробка с яблоками \code{Box<Apple>} и коробка с фруктами \code{Box<Fruit>}, должна ли быть возможность перекинуть из яблочной во фруктовую? Однозначно, нет. Поэтому, в аргументе метода используется \code{Box<? super T>}, таким образом яблоки возможно кидать в яблоки или в яблочных родителей, но не в апельсины.
|
||
\begin{lstlisting}[language=Java,style=JCodeStyle,caption={ }]
|
||
void transferTo(Box<? super T> dest) {
|
||
dest.container.addAll(container);
|
||
container.clear();
|
||
}
|
||
\end{lstlisting}
|
||
|
||
\end{itemize}
|
||
\end{itemize}
|
||
|
||
\subsubsection*{Вопросы и ответы}
|
||
\begin{itemize}
|
||
\item \textbf{Ценность этапа} Вовлечение аудитории в обратную связь, пояснение неочевидных моментов в материале лекции и другой проделанной работе.
|
||
\item \textbf{Тайминг} 5-15 минут
|
||
\item \textbf{Действия преподавателя}
|
||
\begin{itemize}
|
||
\item Преподаватель ожидает вопросов по теме прошедшей лекции, викторины и продемонстрированной работы;
|
||
\item Если преподаватель затрудняется с ответом, необходимо мягко предложить студенту ответить на его вопрос на следующем семинаре (и не забыть найти ответ на вопрос студента!);
|
||
\item Предложить и показать пути самостоятельного поиска студентом ответа на заданный вопрос;
|
||
\item Посоветовать литературу на тему заданного вопроса;
|
||
\item Дополнительно указать на то, что все сведения для выполнения домашнего задания, прохождения викторины и работы на семинаре были рассмотрены в методическом материале к этому или предыдущим урокам.
|
||
\end{itemize}
|
||
\end{itemize}
|
||
|
||
\subsubsection*{Задание 1}
|
||
\begin{itemize}
|
||
\item \textbf{Ценность этапа} Формирование навыков базовой работы с обобщениями.
|
||
\item \textbf{Тайминг} 10-15 мин
|
||
\item \textbf{Действия преподавателя}
|
||
\begin{itemize}
|
||
\item Выдать задание студентам;
|
||
\item Подробно объяснить, что именно требуется от студентов, избегая упоминания конкретных языковых конструкций;
|
||
\item Пояснить студентам пользу и необходимость следования паттерну MVC, проговорить важность разделения логики и открывающиеся возможности при правильном проектировании.
|
||
\end{itemize}
|
||
\item \textbf{Задание}:
|
||
\begin{itemize}
|
||
\item Создать обобщенный класс с тремя параметрами (\code{T}, \code{V}, \code{K}). Класс содержит три переменные типа (\code{T}, \code{V}, \code{K}), конструктор, принимающий на вход параметры типа (\code{T}, \code{V}, \code{K}), методы возвращающие значения трех переменных. Создать метод, выводящий на консоль имена классов для трех переменных класса. Наложить ограничения на параметры типа: \code{T} должен реализовать интерфейс \code{Comparable} (классы оболочки, \code{String}), \code{V} должен реализовать интерфейс \code{DataInput} и расширять класс \code{InputStream}, \code{K} должен расширять класс \code{Number}.
|
||
|
||
\textbf{Вариант решения}
|
||
|
||
\begin{lstlisting}[language=Java,style=JCodeStyle]
|
||
private static class MyClass<T extends Comparable, V extends InputStream & Serializable, K extends Number> {
|
||
T t; V v; K k;
|
||
|
||
MyClass(T t, V v, K k) {
|
||
this.t = t; this.v = v; this.k = k;
|
||
}
|
||
|
||
public T getT() { return t; }
|
||
public V getV() { return v; }
|
||
public K getK() { return k; }
|
||
|
||
void print() {
|
||
System.out.printf("t = %s, v = %s, k = %s",
|
||
t.getClass().getName(),
|
||
v.getClass().getName(),
|
||
k.getClass().getName());
|
||
}
|
||
}
|
||
\end{lstlisting}
|
||
|
||
\end{itemize}
|
||
\end{itemize}
|
||
|
||
\subsubsection*{Задание 2}
|
||
\begin{itemize}
|
||
\item \textbf{Ценность этапа} Практика написания обобщённого кода с дополнительным описанием алгоритмов манипулирования данными.
|
||
\item \textbf{Тайминг} 15-20 мин
|
||
\item \textbf{Действия преподавателя}
|
||
\begin{itemize}
|
||
\item Выдать задание студентам;
|
||
\item Подробно объяснить, что именно требуется от студентов, избегая упоминания конкретных языковых конструкций;
|
||
\item Если группа студентов справилась с заданием, а времени осталось более 5 минут, выдавать группе задания «со звёздочкой».
|
||
\end{itemize}
|
||
\item \textbf{Задание}:
|
||
\begin{itemize}
|
||
\item Описать собственную коллекцию -- список на основе массива. Коллекция должна иметь возможность хранить любые типы данных, иметь методы добавления и удаления элементов.
|
||
|
||
\textbf{Вариант решения}
|
||
|
||
\begin{lstlisting}[language=Java,style=JCodeStyle]
|
||
private static class OwnList<T> {
|
||
Object[] arr;
|
||
int count;
|
||
|
||
OwnList() {
|
||
arr = new Object[1];
|
||
count = 0;
|
||
}
|
||
|
||
void add(T item) {
|
||
if (count == arr.length) {
|
||
Object[] newArr = new Object[arr.length * 2];
|
||
System.arraycopy(arr, 0, newArr, 0, arr.length);
|
||
arr = newArr;
|
||
}
|
||
arr[count++] = item;
|
||
}
|
||
|
||
T remove() {
|
||
if (count == 0) throw new NoSuchElementException();
|
||
T temp = (T) arr[--count];
|
||
arr[count] = null;
|
||
return temp;
|
||
}
|
||
|
||
@Override
|
||
public String toString() {
|
||
return Arrays.toString(arr);
|
||
}
|
||
}
|
||
\end{lstlisting}
|
||
|
||
\end{itemize}
|
||
\end{itemize}
|
||
|
||
\subsubsection*{Задание 3}
|
||
\begin{itemize}
|
||
\item \textbf{Ценность этапа} Изучение поведения итератора для понимания механизмов его действия и необходимости его использования в работе.
|
||
\item \textbf{Тайминг} 20-25 мин
|
||
\item \textbf{Действия преподавателя}
|
||
\begin{itemize}
|
||
\item Выдать задание студентам;
|
||
\item Подробно объяснить, что именно требуется от студентов, избегая упоминания конкретных языковых конструкций;
|
||
\end{itemize}
|
||
\item \textbf{Задание}:
|
||
\begin{itemize}
|
||
\item Написать итератор по массиву. Итератор -- это объект, осуществляющий движение по коллекциям любого типа, содержащим любые типы данных. Итераторы обычно имеют только два метода -- проверка на наличие следующего элемента и переход к следующему элементу. Но также, особенно в других языках программирования, возможно встретить итераторы, реализующие дополнительную логику.
|
||
|
||
\textbf{Вариант решения}
|
||
|
||
\begin{lstlisting}[language=Java,style=JCodeStyle]
|
||
private static class ArrayIterator<T> {
|
||
|
||
private final T[] array;
|
||
private int index = 0;
|
||
|
||
public ArrayIterator(T[] array) {
|
||
this.array = array;
|
||
}
|
||
|
||
public boolean hasNext() {
|
||
return index < array.length;
|
||
}
|
||
|
||
public T next() {
|
||
if(!hasNext())
|
||
throw new NoSuchElementException();
|
||
return array[index++];
|
||
}
|
||
}
|
||
|
||
public static void main(String[] args) {
|
||
Integer[] arr = {1,2,3,4};
|
||
ArrayIterator<Integer> it = new ArrayIterator<>(arr);
|
||
while (it.hasNext()) {
|
||
System.out.print(it.next() + " ");
|
||
}
|
||
}
|
||
\end{lstlisting}
|
||
\item [$*_1$] Написать итератор таким образом, чтобы его возможно было использовать для цикла \code{foreach}.
|
||
|
||
\textbf{Вариант решения}
|
||
|
||
Указать, что для этого достаточно реализовать интерфейс \code{Iterator<T>}.
|
||
|
||
\begin{lstlisting}[language=Java,style=JCodeStyle]
|
||
class ArrayIterator<T> implements Iterator<T>{
|
||
|
||
private T[] array;
|
||
private int index = 0;
|
||
|
||
public ArrayIterator(T[] array) {
|
||
this.array = array;
|
||
}
|
||
|
||
@Override
|
||
public boolean hasNext() {
|
||
return index < array.length;
|
||
}
|
||
|
||
@Override
|
||
public T next() {
|
||
if(!hasNext())
|
||
throw new NoSuchElementException();
|
||
return array[index++];
|
||
}
|
||
}
|
||
\end{lstlisting}
|
||
|
||
\end{itemize}
|
||
\end{itemize}
|
||
|
||
\subsubsection*{Задание 4}
|
||
\begin{itemize}
|
||
\item \textbf{Ценность этапа} Закрепление понимания механизмов работы коллекций (в том числе с применением итераторов).
|
||
\item \textbf{Тайминг} 20-25 мин
|
||
\item \textbf{Действия преподавателя}
|
||
\begin{itemize}
|
||
\item Выдать задание студентам;
|
||
\item Подробно объяснить, что именно требуется от студентов, избегая упоминания конкретных языковых конструкций;
|
||
\end{itemize}
|
||
\item \textbf{Задание}:
|
||
\begin{itemize}
|
||
\item Описать интерфейс \code{Person} с методами \code{doWork()} и \code{haveRest()}. Написать два класса работник и бездельник, реализующих интерфейс. Работник работает, и не умеет бездельничать, в то время как бездельник не умеет работать, но умеет отдыхать. Написать обобщённые классы \code{Workplace} и \code{Club}, содержащие массив из \code{Person}. В классах необходимо вызывать у всего массива людей вызывать соответствующие методы.
|
||
|
||
\textbf{Вариант решения}
|
||
|
||
\begin{lstlisting}[language=Java,style=JCodeStyle]
|
||
interface Person {
|
||
void doWork();
|
||
void haveRest();
|
||
}
|
||
|
||
private static class Worker implements Person {
|
||
@Override public void doWork() {
|
||
System.out.println("Work!"); }
|
||
@Override public void haveRest() {
|
||
System.out.println("What?");
|
||
}
|
||
}
|
||
|
||
private static class Idler implements Person {
|
||
@Override public void doWork() {
|
||
System.out.println("No!"); }
|
||
@Override public void haveRest() {
|
||
System.out.println("Chill!");
|
||
}
|
||
}
|
||
|
||
private static class Workplace<T extends Person> {
|
||
Person[] arr;
|
||
public Workplace(T... people) {
|
||
arr = people;
|
||
}
|
||
void work() {
|
||
for (Person person : arr) { person.doWork(); }
|
||
}
|
||
}
|
||
private static class Club<T extends Person> {
|
||
Person[] arr;
|
||
public Club(T... people) {
|
||
arr = people;
|
||
}
|
||
void chill() {
|
||
for (Person person : arr) { person.haveRest(); }
|
||
}
|
||
}
|
||
|
||
public static void main(String[] args) {
|
||
Workplace<Person> w = new Workplace<>(new Worker(), new Worker(), new Idler());
|
||
Club<Person> c = new Club<>(new Worker(), new Worker(), new Idler());
|
||
w.work();
|
||
c.chill();
|
||
}
|
||
\end{lstlisting}
|
||
|
||
\end{itemize}
|
||
\end{itemize}
|
||
|
||
\subsubsection*{Домашнее задание}
|
||
\begin{itemize}
|
||
\item \textbf{Ценность этапа} Задать задание для самостоятельного выполнения между занятиями.
|
||
\item \textbf{Тайминг} 5-10 минут.
|
||
\item \textbf{Действия преподавателя}
|
||
\begin{itemize}
|
||
\item Пояснить студентам в каком виде выполнять и сдавать задания
|
||
\item Уточнить кто будет проверять работы (преподаватель или ревьювер)
|
||
\item Объяснить к кому обращаться за помощью и где искать подсказки
|
||
\item Объяснить где взять проект заготовки для дз
|
||
\end{itemize}
|
||
\item \textbf{Задания}
|
||
\begin{enumerate}
|
||
\item [5-25 мин] Выполнить все задания семинара, если они не были решены, без ограничений по времени;
|
||
|
||
\textbf{Все варианты решения приведены в тексте семинара выше}
|
||
\item [25 мин] 1. Внедрить итератор из задания 2 в коллекцию, написанную в задании 3 таким образом, чтобы итератор был внутренним классом и, соответственно, объектом в коллекции.
|
||
|
||
\begin{lstlisting}[language=Java,style=JCodeStyle]
|
||
private static class OList<T> implements Iterable<T> {
|
||
class ArrayIterator<T> implements Iterator<T> {
|
||
private int index = 0;
|
||
|
||
@Override
|
||
public boolean hasNext() {
|
||
return index < count;
|
||
}
|
||
|
||
@Override
|
||
public T next() {
|
||
if(!hasNext())
|
||
throw new NoSuchElementException();
|
||
return (T) arr[index++];
|
||
}
|
||
}
|
||
|
||
Object[] arr;
|
||
int count;
|
||
Main.OList.ArrayIterator iter;
|
||
|
||
OList() {
|
||
arr = new Object[1];
|
||
count = 0;
|
||
this.iter = new ArrayIterator<T>();
|
||
}
|
||
|
||
void add(T item) {
|
||
if (count == arr.length) {
|
||
Object[] newArr = new Object[arr.length * 2];
|
||
System.arraycopy(arr, 0, newArr, 0, arr.length);
|
||
arr = newArr;
|
||
}
|
||
arr[count++] = item;
|
||
}
|
||
T remove() {
|
||
if (count == 0) throw new NoSuchElementException();
|
||
--count;
|
||
T temp = (T) arr[count];
|
||
arr[count] = null;
|
||
return temp;
|
||
}
|
||
|
||
@Override
|
||
public Iterator<T> iterator() {
|
||
return iter;
|
||
}
|
||
|
||
@Override
|
||
public Spliterator<T> spliterator() {
|
||
return Iterable.super.spliterator();
|
||
}
|
||
|
||
@Override
|
||
public String toString() {
|
||
return Arrays.toString(arr);
|
||
}
|
||
}
|
||
\end{lstlisting}
|
||
|
||
\item [15 мин] 2. Написать класс Калькулятор (необобщенный), который содержит обобщенные статические методы: \code{sum()}, \code{multiply()}, \code{divide()}, \code{subtract()}. Параметры этих методов -- два \textbf{числа} разного типа, над которыми должна быть произведена операция.
|
||
\begin{lstlisting}[language=Java,style=JCodeStyle]
|
||
private static class Calculator {
|
||
public static <T extends Number, U extends Number> double sum(T num1, U num2) {
|
||
return num1.doubleValue() + num2.doubleValue();
|
||
}
|
||
|
||
public static <T extends Number, U extends Number> double multiply(T num1, U num2) {
|
||
return num1.doubleValue() * num2.doubleValue();
|
||
}
|
||
|
||
public static <T extends Number, U extends Number> double divide(T num1, U num2) {
|
||
return num1.doubleValue() / num2.doubleValue();
|
||
}
|
||
|
||
public static <T extends Number, U extends Number> double subtract(T num1, U num2) {
|
||
return num1.doubleValue() - num2.doubleValue();
|
||
}
|
||
}
|
||
|
||
public static void main(String[] args) {
|
||
System.out.println(Calculator.sum(2, 2.0));
|
||
System.out.println(Calculator.multiply(2.0f, 2.0));
|
||
System.out.println(Calculator.divide(2L, 2.0));
|
||
System.out.println(Calculator.subtract(2, 2));
|
||
}
|
||
\end{lstlisting}
|
||
\item [10 мин] 3. Напишите обобщенный метод \code{compareArrays()}, который принимает два массива и возвращает \code{true}, если они одинаковые, и \code{false} в противном случае. Массивы могут быть любого типа данных, но должны иметь одинаковую длину и содержать элементы одного типа.
|
||
|
||
\begin{lstlisting}[language=Java,style=JCodeStyle]
|
||
private static <T> boolean compareArrays(T[] array1, T[] array2) {
|
||
if (array1.length != array2.length) {
|
||
return false;
|
||
}
|
||
|
||
for (int i = 0; i < array1.length; i++) {
|
||
if (!array1[i].equals(array2[i])) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
\end{lstlisting}
|
||
\item [10 мин] 4. Напишите обобщенный класс \code{Pair}, который представляет собой пару значений разного типа. Класс должен иметь методы \code{getFirst()}, \code{getSecond()} для получения значений пары, а также переопределение метода \code{toString()}, возвращающее строковое представление пары.
|
||
\begin{lstlisting}[language=Java,style=JCodeStyle]
|
||
private static class Pair<T1, T2> {
|
||
private T1 first;
|
||
private T2 second;
|
||
|
||
public Pair(T1 first, T2 second) {
|
||
this.first = first;
|
||
this.second = second;
|
||
}
|
||
|
||
public T1 getFirst() { return first; }
|
||
public T2 getSecond() { return second; }
|
||
|
||
@Override public String toString() {
|
||
return "(" + first + ", " + second + ")";
|
||
}
|
||
}
|
||
|
||
public static void main(String[] args) {
|
||
Pair<Integer, String> pair1 = new Pair<>(1, "one");
|
||
System.out.println(pair1.getFirst()); // 1
|
||
System.out.println(pair1.getSecond()); // "one"
|
||
System.out.println(pair1); // "(1, one)"
|
||
|
||
Pair<String, Double> pair2 = new Pair<>("pi", 3.14);
|
||
System.out.println(pair2.getFirst()); // "pi"
|
||
System.out.println(pair2.getSecond()); // 3.14
|
||
System.out.println(pair2); // "(pi, 3.14)"
|
||
}
|
||
\end{lstlisting}
|
||
\end{enumerate}
|
||
\end{itemize}
|
||
|
||
\subsubsection*{Рефлексия и завершение семинара}
|
||
\begin{itemize}
|
||
\item \textbf{Цель этапа:} Привести урок к логическому завершению, посмотреть что студентам удалось, что было сложно и над чем нужно еще поработать
|
||
\item \textbf{Тайминг:} 5-10 минут
|
||
\item \textbf{Действия преподавателя:}
|
||
\begin{itemize}
|
||
\item Запросить обратную связь от студентов.
|
||
\item Подчеркните то, чему студенты научились на занятии.
|
||
\item Дайте рекомендации по решению заданий, если в этом есть необходимость
|
||
\item Дайте краткую обратную связь студентам.
|
||
\item Поделитесь ощущением от семинара.
|
||
\item Поблагодарите за проделанную работу.
|
||
\end{itemize}
|
||
\end{itemize}
|
||
|
||
\newpage
|
||
\end{document}
|