Задание №3.
Задача: исправить код пакета векторов (интерфейс IVector и реализующие его классы) так, чтобы вектора могли использоваться в стиле foreach цикла — уже была решена ещё в работе №5. Основная схема решения говорила о следующем:
1. Нужно реализовать интерфейс Iterable<Double> классам Array и
CircularLinkedList.
2.Нужно создать классы-итераторы, реализующие интерфейс
Iterator<Double>, внутри классов Array и CircularLinkedList.
3. Нужно создать метод public java.util.Iterator iterator(); в
интерфейсе IVector и реализовать его классам Array и CircularLinkedList. Задание №4.
Добавим в классы векторов версии конструкторов, имеющие параметрами перечисленные элементы вектора (с использованием аргументов переменной длины) (табл. 3, 4).
Таблица 3 — Фрагмент измененного кода vectors/Array.java
package vectors;
import java.io.Serializable;
import java.util.NoSuchElementException; import java.util.Iterator;
import java.lang.Iterable;
public class Array implements IVector, Serializable, Iterable<Double>, Cloneable {
//Конструктор public Array(int n) {
data = new double[n];
}
//Конструктор с переменным числом параметров public Array(double... elements) {
data = new double[elements.length];
for (int i = 0; i < elements.length; ++i) { data[i] = elements[i];
}
}
//...
private final double[] data;
}
Таблица 4 — Фрагмент измененного кода vectors/CircularLinkedList.java
package vectors;
import java.io.Serializable;
import java.util.NoSuchElementException;
7
import java.util.Iterator; import java.lang.Iterable;
public class CircularLinkedList implements IVector, Serializable, Iterable<Double>, Cloneable {
// Конструктор
public CircularLinkedList(int n) {
current = head = new Node(0, null, null); head.prev = head.next = head; current_index = -1;
if (n > 0) {
Node temp = head;
for (int i = 0; i < n; ++i) {
temp = (temp.next = new Node(0, temp, null));
}
temp.next = head; head.prev = temp; size = n;
} else { size = 0;
}
}
//Конструктор с переменным числом параметров public CircularLinkedList(double... elements) {
size = elements.length;
current = head = new Node(0, null, null); head.prev = head.next = head; current_index = -1;
Node temp = head;
for (int i = 0; i < size; ++i) {
temp = (temp.next = new Node(elements[i], temp, null));
}
temp.next = head; head.prev = temp;
}
//...
private Node head, current; private int size, current_index;
}
Создадим файл VarArgsTest.java для проверки работы конструкторов с аргументами переменной длины (табл. 5).
Таблица 5 — Файл VarArgsTest.java
import vectors.Vectors; import vectors.IVector; import vectors.Array;
import vectors.CircularLinkedList; public class VarArgsTest {
public static void main(String[] args) throws Exception { Array array1 = new Array(5);
CircularLinkedList list1 = new CircularLinkedList(5); System.out.print("Array(5): "); array1.print(); System.out.print("CircularLinkedList(5): "); list1.print(); Array array2 = new Array(1.0, 2.0, 3.0);
CircularLinkedList list2 = new CircularLinkedList(1.0, 2.0); System.out.print("Array(1.0, 2.0, 3.0): "); array2.print(); System.out.print("CircularLinkedList(1.0, 2.0): "); list2.print();
}
}
Результат компиляции и запуска приведен на рис. 2. 8
Рисунок 2 — Компиляция и запуск VarArgsTest.java Задание №5.
Исправим метод порождения векторов в классе Vectors, использующий рефлексию, с учетом параметризованности классов Array и CircularLinkedList относительно аргументов переменной длины (табл. 6).
Таблица 6 — Фрагмент измененного кода vectors/Vectors.java
package vectors;
import java.io.IOException; import java.io.Writer; import java.io.Reader; import java.io.InputStream; import java.io.OutputStream;
import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.PrintWriter; import java.io.StreamTokenizer;
import java.lang.reflect.Constructor;
public class Vectors {
//...
//Метод создания вектора фабрики векторов public static IVector createInstance(int n) {
return factory.createVector(n);
}
//Перегруженный метод создания вектора фабрики векторов public static IVector createInstance(int n, IVector vector) {
try {
double[] array = new double[n]; int vectorSize = vector.size();
n = (n < vectorSize) ? n : vectorSize; for (int i = 0; i < n; ++i) {
array[i] = vector.get(i);
}
return vector.getClass().getConstructor(double[].class).newInstance(array);
} catch (Exception e1) { try {
return vector.getClass().getConstructor(Integer.TYPE).newInstance(n);
}
catch (Exception e2) { e2.printStackTrace();
return factory.createVector(n);
}
}
}
// ...
9
// Ссылка на текущую фабрику векторов
private static VectorFactory factory = new ArrayFactory();
}
Создадим файл VarArgsExTest.java для проверки работы конструкторов с аргументами переменной длины (табл. 5).
Таблица 7 — Код VarArgsExTest.java
import vectors.Vectors; import vectors.Array;
import vectors.CircularLinkedList;
public class VarArgsExTest {
public static void main(String[] args) throws Exception { Array array1 = new Array(5);
CircularLinkedList list1 = new CircularLinkedList(5); System.out.print("Array(5): "); array1.print(); System.out.print("CircularLinkedList(5): "); list1.print(); Array array2 = new Array(1.0, 2.0, 3.0);
CircularLinkedList list2 = new CircularLinkedList(1.0, 2.0); System.out.print("Array(1.0, 2.0, 3.0): "); array2.print(); System.out.print("CircularLinkedList(1.0, 2.0): "); list2.print(); System.out.print("-----------\n");
System.out.print("Instance(4, array1): "); Vectors.createInstance(4, array1).print();
System.out.print("Instance(5, array1): "); Vectors.createInstance(5, array1).print();
System.out.print("Instance(6, array1): "); Vectors.createInstance(6, array1).print();
System.out.print("Instance(4, list1): "); Vectors.createInstance(4, list1).print();
System.out.print("Instance(5, list1): "); Vectors.createInstance(5, list1).print();
System.out.print("Instance(6, list1): "); Vectors.createInstance(6, list1).print();
System.out.print("Instance(2, array2): "); Vectors.createInstance(2, array2).print();
System.out.print("Instance(3, array2): "); Vectors.createInstance(3, array2).print();
System.out.print("Instance(4, array2): "); Vectors.createInstance(4, array2).print();
System.out.print("Instance(1, list2): "); Vectors.createInstance(1, list2).print();
System.out.print("Instance(2, list2): "); Vectors.createInstance(2, list2).print();
System.out.print("Instance(3, list2): "); Vectors.createInstance(3, list2).print();
}
}
10