Добавление элемента в позицию 2 2 страница
EL
Ниже приведен фрагмент кода корпоративной системы, где продемонстрированы возможности класса HashMap<K,V> и интерфейса Map.Entry<K,V> при определении прав пользователей.
/* пример # 15 : применение коллекций при проверке доступа в систему :
DemoSecurity.java */
packagechapt10;
import java.util.*;
public class DemoSecurity {
public static void main(String[] args) {
CheckRight.startUsing(2041, "Артем");
CheckRight.startUsing(2420, "Ярослав");
/*
*добавление еще одного пользователя и
* проверка его на возможность доступа
*/
CheckRight.startUsing(2437, "Анастасия");
CheckRight.startUsing(2041, "Артем");
}
}
/* пример # 16 : класс проверки доступа в систему: CheckRight.java */
packagechapt10;
import java.util.*;
public class CheckRight {
private static HashMap<Integer, String> map =
new HashMap<Integer, String> ();
public static void startUsing(int id, String name) {
if (canUse(id)){
map.put(id, name);
System.out.println("доступ разрешен");
} else{
System.out.println("в доступе отказано");
}
}
public static boolean canUse(int id) {
final int MAX_NUM = 2; // заменить 2 на 3
int currNum = 0;
if (!map.containsKey(id))
currNum = map.size();
returncurrNum < MAX_NUM;
}
}
В результате будет выведено:
Доступ разрешен
Доступ разрешен
В доступе отказано
Доступ разрешен,
так как доступ в систему разрешен одновременно только для двух пользователей. Если в коде изменить значение константы MAX_NUM на большее, чем 2, то новый пользователь получит права доступа.
Класс EnumMap<K extends Enum<K>, V> в качестве ключа может принимать только объекты, принадлежащие одному типу enum, который должен быть определен при создании коллекции. Специально организован для обеспечения максимальной скорости доступа к элементам коллекции.
/* пример # 17 : пример работы с классом EnumMap: UseEnumMap.java */
package chapt10;
import java.util.EnumMap;
enum User {
STUDENT, TUTOR, INSTRUCTOR, DEAN
}
class UserPriority {
private int priority;
public UserPriority(User k) {
switch (k) {
case STUDENT:
priority = 1; break;
case TUTOR:
priority = 3; break;
case INSTRUCTOR:
priority = 7; break;
case DEAN:
priority = 10; break;
default:
priority = 0;
}
}
public int getPriority() {
return priority;
}
}
public class UseEnumMap {
public static void main(String[] args) {
EnumMap<User, UserPriority> faculty =
new EnumMap<User, UserPriority> (User.class);
for (User user : User.values()) {
faculty.put(user,
new UserPriority(user));
}
for (User user : User.values()) {
System.out.println(user.name()
+ "-> Priority:" +
((UserPriority) faculty.get(user)).getPriority());
}
}
}
В результате будет выведено:
STUDENT-> Priority:1
TUTOR-> Priority:3
INSTRUCTOR-> Priority:7
DEAN-> Priority:10
Унаследованные коллекции
В ряде распределенных приложений, например с использованием сервлетов, до сих пор применяются коллекции, более медленные в обработке, но при этом потокобезопасные, существовавшие в языке Java с момента его создания, а именно карта Hashtable<K,V>, список Vector<E> и перечисление Enumeration<E>. Все они также были параметризованы, но сохранили все свои особенности.
КлассHashtable<K,V> реализует интерфейс Map, но обладает также несколькими интересными методами:
Enumeration<V> elements() – возвращает перечисление (аналог итератора) для значений карты;
Enumeration<K> keys() – возвращает перечисление для ключей карты.
/* пример # 18 : создание хэш-таблицы и поиск элемента по ключу:
HashTableDemo.java */
packagechapt10;
import java.util.*;
import java.io.*;
public class HashTableDemo {
public static void main(String[] args) {
Hashtable<Integer, Double> ht =
new Hashtable<Integer, Double>();
for (int i = 0; i < 5; i++)
ht.put(i, Math.atan(i));
Enumeration<Integer> ek = ht.keys();
int key;
while (ek.hasMoreElements()) {
key = ek.nextElement();
System.out.printf("%4d ", key);
}
System.out.println("");
Enumeration<Double> ev = ht.elements();
double value;
while (ev.hasMoreElements()) {
value = ev.nextElement();
System.out.printf("%.2f ", value);
}
}
}
В результате в консоль будет выведено:
4 3 2 1 0
1,33 1,25 1,11 0,79 0,00
Принципы работы с коллекциями, в отличие от их структуры, со сменой версий языка существенно не изменились.
Класс Collections
Класс Collections содержит большое количество статических методов, предназначенных для манипулирования коллекциями.С применением предыдущих версий языка было разработано множество коллекций, в которых никаких проверок нет, следовательно, при их использовании нельзя гарантировать, что в коллекцию не будет помещен “посторонний” объект. Для этого в класс Collections был добавлен новый метод – checkedCollection(): public static <E> Collection <E> checkedCollection(Collection<E> c, Class<E> type)Этот метод создает коллекцию, проверяемую на этапе выполнения, то есть
в случае добавления “постороннего” объекта генерируется исключение ClassCastException:
/* пример # 19 : проверяемая коллекция: SafeCollection.java */
packagechapt10;
import java.util.*;
public class SafeCollection {
public static void main(String args[]) {
Collection c = Collections.checkedCollection(
new HashSet<String>(), String.class);
c.add("Java");
c.add(7.0); // ошибка времени выполнения
}
}
В этот же класс добавлен целый ряд методов, специализированных для проверки конкретных типов коллекций, а именно: checkedList(),
checkedSortedMap(), checkedMap(), checkedSortedSet(),
checkedSet(), а также:
<T> boolean addAll(Collection<? super T> c, T... a) – добавляет в параметризованную коллекцию соответствующие параметризации элементы;
<T> void copy(List<? super T> dest, List<? extends T> src) – копирует все элементы из одного списка в другой;
boolean disjoint(Collection<?> c1, Collection<?> c2) – возвращает true, если коллекции не содержат одинаковых элементов;
<T> List <T> emptyList(), <K,V> Map <K,V> emptyMap(),
<T> Set <T> emptySet() – возвращают пустой список, карту отображения
и множество соответственно;
<T> void fill(List<? super T> list, T obj) – заполняет список заданным элементом ;
int frequency(Collection<?> c, Object o) – возвращает количество вхождений в коллекцию заданного элемента;
<T extends Object & Comparable <? super T>> T max(Collection<? extends T> coll),
<T extends Object & Comparable <? super T>> T min(Collection<? extends T> coll)– возвращают минимальный
и максимальный элемент соответственно;
<T> T max(Collection <? extends T> coll,
Comparator<? super T> comp),
<T> T min(Collection<? extends T> coll,
Comparator<? super T> comp) – возвращают минимальный и максимальный элемент соответственно, используя Comparator для сравнения;
<T> List <T> nCopies(int n, T o) – возвращает список из nзаданных элементов;
<T> boolean replaceAll(List<T> list, T oldVal, T newVal) – заменяет все заданные элементы новыми;
void reverse(List<?> list) – “переворачивает” список;
void rotate(List<?> list, int distance) – сдвигает список циклически на заданное число элементов;
void shuffle(List<?> list) – перетасовывает элементы списка;
<T> Set <T> singleton(T o), singletonList(T o), singletonMap(K key, V value) – создают множество, список и карту отображения, состоящие из одного элемента;
<T extends Comparable<? super T>> void sort(List<T> list),
<T> void sort(List<T> list, Comparator<? super T> c) – сортировка списка, естественным порядком и используя Comparator соответственно;
void swap(List<?> list, int i, int j) – меняет местами элементы списка стоящие на заданных позициях.
/* пример # 20 : методы класса Collections: CollectionsDemo.java:
MyComparator.java */
package chapt10;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class CollectionsDemo {
public static void main(String[] args) {
MyComparator<Integer> comp =
new MyComparator<Integer>();
ArrayList<Integer> list =
new ArrayList<Integer>();
Collections.addAll(list, 1, 2, 3, 4, 5);
Collections.shuffle(list);
print(list);
Collections.sort(list, comp);
print(list);
Collections.reverse(list);
print(list);
Collections.rotate(list, 3);
print(list);
System.out.println("min: "
+ Collections.min(list, comp));
System.out.println("max: "
+ Collections.max(list, comp));
List<Integer> singl =
Collections.singletonList(71);
print(singl);
//singl.add(21);//ошибка времени выполнения
}
static void print(List<Integer> c) {
for (int i : c)
System.out.print(i + " ");
System.out.println();
}
}
package chapt10;
import java.util.Comparator;
public class MyComparator<T> implements Comparator<Integer> {
public int compare(Integer n, Integer m) {
return m.intValue() - n.intValue();
}
}
В результате будет выведено:
4 3 5 1 2
5 4 3 2 1
1 2 3 4 5
3 4 5 1 2
min: 5
max: 1
Класс Arrays
В пакете java.util находится класс Arrays, который содержит методы манипулирования содержимым массива, а именно для поиска, заполнения, сравнения, преобразования в коллекцию и прочие:
int binarySearch(параметры) – перегруженный метод организации бинарного поиска значения в массивах примитивных и объектных типов. Возвращает позицию первого совпадения;
void fill(параметры) – перегруженный метод для заполнения массивов значениями различных типов и примитивами;
void sort(параметры) – перегруженный метод сортировки массива или его части с использованием интерфейса Comparator и без него;
static <T> T[] copyOf(T[] original, int newLength) –заполняет массив определенной длины, отбрасывая элементы или заполняя null при необходимости;
static <T> T[] copyOfRange(T[] original, int from, int to) – копирует заданную область массива в новый массив;
<T> List<T> asList(T... a) – метод, копирующий элементы массива в объект типа List<T>.
В качестве простого примера применения указанных методов можно привести следующий код.
/* пример # 21 : методы класса Arrays : ArraysEqualDemo.java */
packagechapt10;
import java.util.*;
public class ArraysEqualDemo {
public static void main(String[] args) {
char m1[] = new char[3];
charm2[] = { 'a', 'b', 'c' }, i;
Arrays.fill(m1, 'a');
System.out.print("массив m1:");
for (i = 0; i < 3; i++)
System.out.print(" " + m1[i]);
m1[1] = 'b';
m1[2] = 'c';
//m1[2]='x'; // приведет к другому результату
if (Arrays.equals(m1, m2))
System.out.print("\nm1 и m2 эквивалентны");
Else
System.out.print("\nm1 и m2 не эквивалентны");
m1[0] = 'z';
Arrays.sort(m1);
System.out.print("\nмассив m1:");
for (i = 0; i < 3; i++)
System.out.print(" " + m1[i]);
System.out.print(
"\n значение 'c' находится в позиции-"
+ Arrays.binarySearch(m1, 'c'));
Integer arr[] = {35, 71, 92};
//вывод массива объектов в строку
System.out.println(Arrays.deepToString(arr));
//вычисление хэш-кода исходя и значений элементов
System.out.println(Arrays.deepHashCode(arr));
Integer arr2[] = {35, 71, 92};
//сравнение массивов по седержимому
System.out.println(Arrays.deepEquals(arr, arr2));
char m3[] = new char[5];
// копирование массива
m3 = Arrays.copyOf(m1, 5);
System.out.print("массив m3:");
for (i = 0; i < 5; i++)
System.out.print(" " + m3[i]);
}
}
В результате компиляции и запуска будет выведено:
массив m1: a a a
M1 и m2 эквивалентны
массив m1: b c z
значение 'c' находится в позиции 1
[35, 71, 92]
True
массив m3: b c z □ □
Задания к главе 10
Вариант A
1. Ввести строки из файла, записать в список. Вывести строки в файл в обратном порядке.
2. Ввести число, занести его цифры в стек. Вывести число, у которого цифры идут в обратном порядке.
3. Создать в стеке индексный массив для быстрого доступа к записям в бинарном файле.
4. Создать список из элементов каталога и его подкаталогов.
5. Создать стек из номеров записи. Организовать прямой доступ к элементам записи.
6. Занести стихотворения одного автора в список. Провести сортировку по возрастанию длин строк.
7. Задать два стека, поменять информацию местами.
8. Определить множество на основе множества целых чисел. Создать методы для определения пересечения и объединения множеств.
9. Списки (стеки, очереди) I(1..n) и U(1..n) содержат результаты n-измерений тока и напряжения на неизвестном сопротивлении R. Найти приближенное число R методом наименьших квадратов.
10. С использованием множества выполнить попарное суммирование произвольного конечного ряда чисел по следующим правилам: на первом этапе суммируются попарно рядом стоящие числа, на втором этапе суммируются результаты первого этапа и т.д. до тех пор, пока не останется одно число.
11. Сложить два многочлена заданной степени, если коэффициенты многочленов хранятся в объекте HashMap.
12. Умножить два многочлена заданной степени, если коэффициенты многочленов хранятся в различных списках.
13. Не используя вспомогательных объектов, переставить отрицательные элементы данного списка в конец, а положительные – в начало этого списка.
14. Ввести строки из файла, записать в список ArrayList. Выполнить сортировку строк, используя метод sort() из классаCollections.
15. Задана строка, состоящая из символов '(', ')', '[', ']', '{', '}'. Проверить правильность расстановки скобок. Использовать стек.
16. Задан файл с текстом на английском языке. Выделить все различные слова. Слова, отличающиеся только регистром букв, считать одинаковыми. Использовать класс HashSet.
17. Задан файл с текстом на английском языке. Выделить все различные слова. Для каждого слова подсчитать частоту его встречаемости. Слова, отличающиеся регистром букв, считать различными. Использовать класс HashMap.
Вариант B
1. В кругу стоят N человек, пронумерованных от 1 до N. При ведении счета по кругу вычеркивается каждый второй человек, пока не останется один. Составить две программы, моделирующие процесс. Одна из программ должна использовать класс ArrayList, а вторая – LinkedList. Какая из двух программ работает быстрее? Почему?
2. Задан список целых чисел и число X. Не используя вспомогательных объектов и не изменяя размера списка, переставить элементы списка так, чтобы сначала шли числа, не превосходящие X, а затем числа, большие X.
3. Написать программу, осуществляющую сжатие английского текста. Построить для каждого слова в тексте оптимальный префиксный код по алгоритму Хаффмена. Использовать класс PriorityQueue.
4. Реализовать класс Graph, представляющий собой неориентированный граф. В конструкторе класса передается количество вершин в графе. Методы должны поддерживать быстрое добавление и удаление ребер.
5. На базе коллекций реализовать структуру хранения чисел с поддержкой следующих операций:
· добавление/удаление числа;
· поиск числа, наиболее близкого к заданному (т.е. модуль разницы минимален).
6. Реализовать класс, моделирующий работу N-местной автостоянки. Машина подъезжает к определенному месту и едет вправо, пока не встретится свободное место. Класс должен поддерживать методы, обслуживающие приезд и отъезд машины.
7. Во входном файле хранятся две разреженные матрицы А и В. Построить циклически связанные списки СА и СВ, содержащие ненулевые элементы соответственно матриц А и В. Просматривая списки, вычислить: а) сумму S = A + B; б) произведение P = A * B.
8. Во входном файле хранятся наименования некоторых объектов. Построить список C1, элементы которого содержат наименования и шифры данных объектов, причем элементы списка должны быть упорядочены по возрастанию шифров. Затем “сжать” список C1, удаляя дублирующие наименования объектов.
9. Во входном файле расположены два набора положительных чисел; между наборами стоит отрицательное число. Построить два списка C1 и С2, элементы которых содержат соответственно числа 1-го и 2-го набора таким образом, чтобы внутри одного списка числа были упорядочены по возрастанию. Затем объединить списки C1 и С2 в один упорядоченный список, изменяя только значения полей ссылочного типа.
10. Во входном файле хранится информация о системе главных автодорог, связывающих г.Минск с другими городами Беларуси. Используя эту информацию, постройте дерево, отображающее систему дорог республики, а затем, продвигаясь по дереву, определить минимальный по длине путь из г.Минска в другой заданный город. Предусмотреть возможность для последующего сохранения дерева в виртуальной памяти.
11. Один из способов шифрования данных, называемый «двойным шифрованием», заключается в том, что исходные данные при помощи некоторого преобразования последовательно шифруются на некоторые два ключа K1 и K2. Разработать и реализовать эффективный алгоритм, позволяющий находить ключи K1 и K2 по исходной строке и ее зашифрованному варианту. Проверить, оказался ли разработанный способ действительно эффективным, протестировав программу для случая, когда оба ключа К1 и К2 являются 20-битными (время ее работы не должно превосходить одной минуты).
12. На плоскости задано N точек. Вывести в файл описания всех прямых, которые проходят более чем через одну точку из заданных. Для каждой прямой указать, через сколько точек она проходит. Использовать класс HashMap.
13. На клетчатой бумаге нарисован круг. Вывести в файл описания всех клеток, целиком лежащих внутри круга, в порядке возрастания расстояния от клетки до центра круга. Использовать класс PriorityQueue.
14. На плоскости задано N отрезков. Найти точку пересечения двх отрезков, имеющую минимальную абсциссу. Использовать класс TreeMap.
15. На клетчатом листе бумаги закрашена часть клеток. Выделить все различные фигуры, которые образовались при этом. Фигурой считается набор закрашенных клеток, достижимых друг из друга при движении
в четырёх направлениях. Две фигуры являются различными, если их нельзя совместить поворотом на угол, кратный 90 градусам, и параллельным переносом. Используйте класс HashSet.
16. Дана матрица из целых чисел. Найти в ней прямоугольную подматрицу, состоящую из максимального количества одинаковых элементов. Использовать класс Stack.
17. Реализовать структуру "черный ящик", хранящую множество чисел и имеющую внутренний счетчик K, изначально равный нулю. Структура должна поддерживать операции добавления числа в множество и возвращение K-го по минимальности числа из множества.
18. На прямой гоночной трассе стоит N автомобилей, для каждого из которых известны начальное положение и скорость. Определить, сколько произойдет обгонов.
19. На прямой гоночной трассе стоит N автомобилей, для каждого из которых известны начальное положение и скорость. Вывести первые K обгонов.
Тестовые задания к главе 10
Вопрос 10.1.
Какой интерфейс наиболее пригоден для создания класса, содержащего несортированные уникальные объекты?
1) Set;
2) List;
3) Map;
4) Vector;
5) нет правильного ответа.
Вопрос 10.2.
Какие из фрагментов кода создадут объект класса ArrayList и добавят элемент?
1) ArrayList a = new ArrayList(); a.add(“0”);
2) ArrayList a = new ArrayList(); a[0]=“0”;
3) List a = new List(); a.add(“0”);
4) List a = new ArrayList(10); a.add(“0”);
Вопрос 10.3.
Какой интерфейс реализует класс Hashtable?
1) Set;
2) Vector;
3) AbstractMap;
4) List;
5) Map.
Вопрос 10.4.
Дан код:
import java.util.*;class Quest4 {public static void main (String args[]) { Object ob = new HashSet();System.out.print((ob instanceof Set) + ", ");System.out.print(ob instanceof SortedSet);}}Что будет выведено при попытке компиляции и запуска программы?
1) true, false;
2) true, true;
3) false, true;
4) false, false;
5) ничего из перечисленного.
Вопрос 10.5.
Какие из приведенных ниже названий являются именами интерфейсов пакета java.util?
1) SortedMap;
2) HashMap;
3) HashSet;
4) SortedSet;
5) Stack;
6) AbstractMap.
ГРАФИЧЕСКИЕ ИНТЕРФЕЙСЫ ПОЛЬЗОВАТЕЛЯ
Основы оконной графики
Для поддержки пользовательских интерфейсов язык Java содержит библиотеки классов, позволяющие создавать и поддерживать окна, использовать элементы управления (кнопки, меню, полосы прокрутки и др.), применять инструменты для создания графических приложений. Графические инструменты и интерфейсы пользователя в языке Java реализованы с помощью двух библиотек:
· Пакет AWT(загружается java.awt) содержит набор классов, позволяющих выполнять графические операции и создавать элементы управления. Этот пакет поддерживается последующими версиями языка, однако считается весьма ограниченным и недостаточно эффективным.
· Пакет Swing (загружается javax.swing, имя javax обозначает, что пакет не является основным, а только расширением языка) содержит улучшенные и обновленные классы, по большей части аналогичные AWT. К именам этих классов добавляется J (JButton, JLabel
и т.д.). Пакет является частью библиотеки JFC (Java Foundation Classes), которая содержит большой набор компонентов JavaBeans, предназначенных для создания пользовательских интерфейсов.
Библиотека Swing, в отличие от AWT, более полно реализует парадигму объектно-ориентированного программирования. К преимуществам библиотеки Swing следует отнести повышение надежности, расширение возможностей пользовательского интерфейса, а также независимость от платформы. Кроме того, библиотеку Swing легче использовать, она визуально более привлекательна.
Работа с окнами и графикой в Java осуществляется в апплетах и графических приложениях. Апплеты – это небольшие программы, встраиваемые в Web-документ и использующие для своей визуализации средства Web-браузера. Графические приложения сами отвечают за свою прорисовку.
Апплеты используют окна, производные от класса Panel, графические приложения используют окна, производные от класса Frame, порожденного от классаWindow.
Иерархия базовых классов AWT и Swing, применяемых для построения визуальных приложений, приведена на рисунке 11.1.
Суперклассjava.awt.Component является абстрактным классом, инкапсулирующим все атрибуты визуального компонента. Класс содержит большое число методов для создания компонентов управления и событий, с ними связанных.
Рис. 11.1. Иерархия классов основных графических компонентов AWT и Swing
Порожденный от него подкласс Container содержит методы типа add(), которые позволяют вкладывать в него другие компоненты (объекты) и отвечает за размещение любых компонентов, которые он содержит. Класс Container порождает классы Panel и Window – фундаментальные классы при создании апплетов и фреймов.