lab03-ready / lab03-collections
.rtfЛабораторная работа №3. Работа с списками.
-
Цель работы
Применить на практике возможности "Java Collections Framework" (JCF).
-
Примеры.
Приведём generic-код для определения элементов, которые входят в один список, но не входят в другой:
public class DemoGetUnigueItems {
/**
* Выделить из списка a элементы, которых нет в списке b
* @param a
* @param b
* @param <T> тип элементов списков
* @return список уникальных элементов списка a
*/
public static <T> List<T> getUnigueItems(Collection<T> a, Collection<T> b) {
if (a == null) {
return null;
}
// в результат включаем пока все элементы списка a ...
final ArrayList<T> result = new ArrayList<T>(a);
if (b != null && !b.isEmpty()) {
// убрать из результата всё что есть в непустом b ...
/*
* простой вариант
result.removeAll(b);
* будет крайне неэффективным если b содержит много элементов и не
* является Set, т.к. много времени будет уходить на проверку наличия
* элемента в b (во время вызова result.removeAll).
* Для гарантии быстрой работы здесь создаём, при необходимости, Set,
* чтобы второй список мог быстро выполнять проверки наличия...
*/
final Set<T> fastB = (b instanceof Set) ? (Set) b : new HashSet<T>(b);
result.removeAll(fastB);
}
return result;
}
/**
* Пример использования этого метода
*/
public static void main(String[] args) {
try {
final List<String> aa = Arrays.asList( "a", "b", "c");
final List<String> bb = Arrays.asList( "A", "b", "d");
System.out.println("aa="+ aa); // aa=[a, b, c]
System.out.println("bb="+ bb); // bb=[A, b, d]
System.out.println("aa - bb ="+ Tools.getUnigueItems(aa, bb)); // aa - bb =[a, c]
System.out.println("bb - aa ="+ Tools.getUnigueItems(bb, aa)); // bb - aa =[A, d]
} catch (Throwable ex) {
ex.printStackTrace();
}
}
}
См также прилагающиеся примеры DemoArrayToList.java и DemoCollections.java.
Также, примеров много в Сети и литературе.
-
Задание ЛР №3 ( 4 балла + доп для вариантов усложнений).
Во входном текстовом файле содержатся данные двух текстовых списков A и B, в виде
>>>
Целое n - кол-во элементов в списке A
элемент 1 списка A
...
элемент n списка A
Целое m - кол-во элементов в списке B
элемент 1 списка B
...
элемент m списка B
<<<
Загрузить эти данные используя ArrayList или другие подходящие классы JCF.
Сравнить списки и вывести в выходной текстовый файл результат сравнения в виде таблицы:
№ Элемент Наличие в A Наличие в B
1 ... +/- +/-
2 ... +/- +/-
3 ... +/- +/-
где в столбце "Элемент" перечисляются все элементы из объединения списков A и B, а столбцах наличия выводится "+", если элемент присутствует в соответствующем списке и "-" иначе.
Усложнения, каждое из которых увеличивает Ваш общий бал на дополнительную величину:
1) (доп +1 балл) В некоторых строках входного файла могут содержаться комментарии, которые должны игнорироваться при чтении данных. Комментарием считается вся строка целиком или часть строки, начиная с символов '#', ';' или пары символов прямой слеш "//".
2) (доп +1 балл) Выводимая таблица должна быть отсортирована по алфавиту.
3) (доп +1 балла) Выводимые данные должны содержать исходные номера (не индексы) элементов в каждом списке.
4) (доп +3 балла) Комментарии могут быть частью строки и многострочными. Такие комментарии начинаются с пары символов "/*" и заканчиваются парой "*/", или между "{" и заканчиваться "}". Причём, начало и конец могут располагаться внутри строк, не обязательно в начале строки. Также в строке могут иметься несколько разных видов комментариев.
Например,
23 { комментарий } 2 /* ещё один */ 33 67 // ещё {а этот комментарий уже не учитывается, т.к. он внутри //
Например, для входного файла:
3 # первый список A содержит три элемента
Urals // у этого элемента индекс внутри A это [0], а номер [1]
Родина
Россия
2 // второй список B два
time
Urals
Результат будет такой (в варианте всех усложнений: с отслеживанием комментариев, с сортировкой и исходными номерами):
№ Элемент Наличие в A Наличие в B
1 "Родина" + [2] -
2 "Россия" + [3] -
3 "time" - + [1]
4 "Urals" + [1] + [2]
На что следует обратить внимание:
1) Программа должны быть структурирована - т.е. в ней должны быть выделены методы, которые:
-
выполняют действия, логически независимые или значимые для алгоритма. В данном случае это ввод списка строк, вывод списка, сравнение списков.
-
содержат повторяющиеся последовательности действий - здесь это ввод и вывод списков, проверка комментариев,
-
возможно, что-то ещё потребует выделения в отдельные методы.
2) Программа должна хорошо читаться -- глядя на текст, должно быть понятно что происходит в каждой точке. Если выполняются требования п 1 многое в программе будет удовлетворять требованию читабельности, но всё равно будут некоторые моменты, которые дополнительно надо комментировать прямо в тексте.
3) По оформлению: используйте встроенные средства javadoc, отступами принято выделать новые программные блоки (т.е. внутри скобок {}). Причём, один отступ на блок. Хорошим стилем можно считать использование табуляций для отступов.
Например:
while (true) {
final Integer X = getInt(buff); // здесь сразу пропускаются комментарии
if (X == null) // получение null означает достижение конца файла
break;
lines++; // счётчик данных
if (X >= A && X <= B) {
found++; // счётчик отфильтрованных
System.out.println(String.format("[%s] %s", found, X));
}
} // while
[конец]