08. Хэш-множество
Если в множестве нужно хранить большие объекты, а не целые числа, то полная проверка на равенство обойдётся слишком дорого.
Лучше для каждого объекта сначала считать некоторую сводную величину, которая будет занимать меньше места и при этом будет равна у равных объектов.
Лучше всего для такого сведения подходят хэш-функции. Сам результат сведения называют хэшем
объекта. В java хэш-функция всегда возвращает переменную типа int,
подробнее о хэшах можно прочитать здесь
Такое множество должно хранить два массива: массив ссылок на объекты и массив хэшей. Сначала для нового объекта высчитывается хэш, потом этот хэш ищется в массиве хэшей, для всех индексов, значения которых совпали с хэшем нового объекта, выполняется проверка самих объектов на равенство. Если ни один хэш не совпал, то и объектов, равных новому точно нет.
В данном блоке требуется разработать множество, хранящее строки.
У строк есть готовые методы сравнения .equals() расчёта хэша .hashCode():
public class Main {
public static void main(String[] args) {
String a = "TEST";
String b = "TEST";
String c = "TEST2";
System.out.println(a.equals(b) + " " + b.equals(c));
System.out.println(a.hashCode() + " " + b.hashCode() + " " + c.hashCode());
}
}
На консоль будет выведено:
true false
2571410 2571410 79713760
Задание
Это задание рассчитано на два урока, за него будет выставлено две оценки
На основе множества MySet из предыдущего задания требуется написать
класс хэш-множества строк MyHashSet (массив элементов должен хранить строки):
Использовать встроенные коллекции java запрещается. Перед каждой проверкой на равенство должна быть проверка хэшей
- Поле
elements, в нём должны храниться элементы множества, а также полеelemCnt, хранящее количество сохранённых элементов. - Конструктор по умолчанию
MyHashSet(), в нём должен инициализироваться массив строкelementsдесятью пустыми строковыми элементами. Количество элементовelemCntдолжно быть равно . - Конструктор копии
MyHashSet(MyHashSet mySet), который на основе множества, переданной в аргументе, инициализирует поля копиями полей полученной из аргументов множества String [] getData()- возвращает копию массиваelements, но копироваться должны только сохранённые элементы (доelemCnt)int [] getHashes()- возвращает копию массива хэшей, но копироваться должны только сохранённые элементы (доelemCnt)boolean add(String v), он должен добавлять новый элемент в множество (в конец массива). При добавлении элементов в множество необходимо добавлять новый элемент в позицию с индексом, равным количеству уже добавленных элементов. Если массив уже полностью заполнен, то необходимо создать новый, в два полтора больший, и скопировать в него все элементы исходного массива. После этого необходимо добавить новый элемент. При добавлении Метод должен увеличивать количество добавленных элементов множества на . Перед добавлением необходимо проверить, нет ли уже такого элемента в множестве. Если такой элемент уже есть, то возвращаетfalse, иначеtrue. Первоначальный размер массива элементов должен быть равен двумboolean remove(String v)- удаляет элемент, равный переданному в аргументах из множества (не только из массива), возвращаетtrue, если такой элемент был иfalse, если нетboolean contains(String v)- возвращаетtrue, если в множества есть хотя бы один элемент, равный переданному в аргументах иfalse, если нетboolean addAll(MyHashSet mySet)- добавляет в множество все элементы множества, переданной в аргументах по той же логике, что иvoid add(int v). Возвращаетtrueboolean containsAll(MyHashSet mySet)- возвращаетtrue, если в множества присутствует каждый из элементов переданной в аргументах множестваboolean removeAll(MyHashSet mySet)- удаляет все элементы, содержащиеся в множествеmySetвозвращаетtrue, если был удалён хотя бы один элементboolean retainAll(MyHashSet mySet)- оставляет только те элементы, которые есть вmySetвозвращаетtrue, если множество было изменено
Все поля и методы должны иметь модификатор public