Карты отображений в Java

Карта отображений – это объект, который хранит пару “ключ-значение”. Поиск объекта (значения) облегчается по сравнению с множествами за счет того, что его можно найти по его уникальному ключу. Уникальность объектов-ключей должна обеспечиваться переопределением методов hashCode() и equals() пользовательским классом. Если элемент с указанным ключом отсутствует в карте, то возвращается значение null.

Классы карт отображений:

AbstractMap<K,V> – реализует интерфейс Map<K,V>;

HashMap<K,V> – расширяет AbstractMap<K,V>, используя хэш-таблицу, в которой ключи отсортированы относительно значений их хэш-кодов;

TreeMap<K,V> – расширяет AbstractMap<K,V>, используя дерево, где ключи расположены в виде дерева поиска в строгом порядке.

WeakHashMap<K,V> позволяет механизму сборки мусора удалять из карты значения по ключу, ссылка на который вышла из области видимости приложения.

LinkedHashMap<K,V> запоминает порядок добавления объектов в карту и образует при этом дважды связанный список ключей. Этот механизм эффективен, только если превышен коэффициент загруженности карты при работе с кэш-памятью и др.

clip_image002

Рис. 10.3. Иерархия наследования карт

Для класса IdentityHashMap<K,V> хэш-коды объектов-ключей вычисляются методом System.identityHashCode() по адресу объекта в памяти, в отличие от обычного значения hashCode(), вычисляемого сугубо по содержимому самого объекта.

Интерфейсы карт:

Map<K,V> – отображает уникальные ключи и значения;

Map.Entry<K,V> – описывает пару “ключ-значение”;

SortedMap<K,V> – содержит отсортированные ключи и значения;

NavigableMap<K,V> – добавляет новые возможности поиска по ключу.

Интерфейс Map<K,V> содержит следующие методы:

void clear() – удаляет все пары из вызываемой карты;

boolean containsKey(Object key) – возвращает true, если вызывающая карта содержит key как ключ;

boolean containsValue(Object value) – возвращает true, если вызывающая карта содержит value как значение;

Set<Map.Entry<K,V>> entrySet() – возвращает множество, содержащее значения карты;

Set<K> keySet() – возвращает множество ключей;

V get(Object obj) – возвращает значение, связанное с ключом obj;

V put(K key, V value) – помещает ключ key и значение value в вызывающую карту. При добавлении в карту элемента с существующим ключом произойдет замена текущего элемента новым. При этом метод возвратит заменяемый элемент;

void putAll(Map <? extends K, ? extends V> t) – помещает коллекцию t в вызывающую карту;

V remove(Object key) – удаляет пару “ключ-значение” по ключу key;

Collection<V> values() – возвращает коллекцию, содержащую значения карты.

Интерфейс Map.Entry<K,V> содержит следующие методы:

K getKey() – возвращает ключ текущего входа;

V getValue() – возвращает значение текущего входа;

V setValue(V obj) – устанавливает значение объекта obj в текущем входе.

В примере показаны способы создания хэш-карты и доступа к ее
элементам.

/* пример # 14 : создание хэш-карты и замена элемента по ключу:

DemoHashMap.java */

package chapt10;

import java.util.*;

public class DemoHashMap {

public static void main(String[] args){

HashMap<Integer, String> hm =

new HashMap<Integer, String>(5);

for (int i = 11; i < 15; i++)

hm.put(i, i + "EL");

System.out.println(hm);

hm.put(12, "14EL");

System.out.println(hm + "с заменой элемента");

String a = hm.get(12);

System.out.println(a + " – найден по ключу ’12’");

/* вывод хэш-таблицы с помощью методов интерфейса

Map.Entry<K,V> */

Set<Map.Entry<Integer, String>> setvalue =

hm.entrySet();

System.out.println(setvalue);

Iterator<Map.Entry<Integer, String>> i =

setvalue.iterator();

while (i.hasNext()) {

Map.Entry<Integer, String> me = i.next();

System.out.print(me.getKey()+" : ");

System.out.println(me.getValue());

}

}

}

{13=13EL, 14=14EL, 12=12EL, 11=11EL}

{13=13EL, 14=14EL, 12=14EL, 11=11EL}с заменой элемента

14EL – найден по ключу ’12’

[13=13EL, 14=14EL, 12=14EL, 11=11EL]

13 : 13EL

14 : 14EL

12 : 14EL

11 : 11EL

Ниже приведен фрагмент кода корпоративной системы, где продемонстрированы возможности класса HashMap<K,V> и интерфейса Map.Entry<K,V> при определении прав пользователей.

/* пример # 15 : применение коллекций при проверке доступа в систему :

DemoSecurity.java */

package chapt10;

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 */

package chapt10;

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();

return currNum < 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

Вы можете следить за любыми ответами на эту запись через RSS 2.0 ленту. Вы можете оставить ответ, или trackback с вашего собственного сайта.

Оставьте отзыв

XHTML: Вы можете использовать следующие теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

 
Rambler's Top100