Главная » Java » Класс BitSet

0

позволяет создать битовый вектор, размер которого изменяется динамически. Фактически BitSet представляет собой набор битов со значениями true или false размером до 232–1, причем изначально все биты равны false. Для хранения набора выделяется объем памяти, необходимый для хранения вектора вплоть до старшего бита, который устанавливался или сбрасывался в программе — все превышающие его биты считаются равными false.

При создании объекта BitSet можно явно задать исходный размер набора или воспользоваться безаргументным конструктором для установки размера по умолчанию.

public void set(int bit)

Устанавливает бит в позиции bit, присваивая ему значение true. public void clear(int bit)

Сбрасывает бит в позиции bit, присваивая ему значение false. public boolean get(int bit)

Возвращает значение бита в позиции bit. public void and(BitSet other)

Выполняет операцию логического И над данным набором и other и присваивает результат

данному набору.

public void or(BitSet other)

Выполняет операцию логического ИЛИ над данным набором и other и присваивает результат данному набору.

public void xor(BitSet other)

Выполняет операцию исключающего логического ИЛИ над данным набором и other и присваивает результат данному набору.

public int size()

Возвращает позицию старшего бита в наборе, который может быть установлен или сброшен без необходимости увеличения набора.

public int hashCode()

Возвращает хеш-код для набора, определяемый значениями битов. Соблюдайте осторожность и не изменяйте биты набора, пока объект BitSet находится в хеш-таблице, иначе он будет потерян.

public boolean equals(BitSet other)

Возвращает true, если все биты other совпадают с битами в данном наборе.

В приведенном ниже классе с помощью объекта BitSet происходит пометка символов, встречающихся  в строке. Объект можно распечатать и посмотреть, какие же символы входят в строку:

public class WhichChars {

private BitSet used = new BitSet();

public WhichChars(String str) {

for (int i = 0; i << str.length(); i++)

used.set(str.charAt(i));   // установить бит,

// соответствующий символу

}

public String toString() { String desc = "[";

int size = used.size();

for (int i = 0; i << size; i++) {

if (used.get(i))

desc += (char)i;

}

return desc + "]";

}

}

12.2. Интерфейс Enumeration

Большинство классов-коллекций  использует интерфейс Enumeration в качестве средства для перебора объектов, входящих в коллекцию. Кроме того, этот интерфейс используется и другими классами, входящими в библиотеки Java, а также в пользовательские программы. Обычно при этом создается собственный класс, который реализует интерфейс Enumeration и содержит один или несколько методов, возвращающих объект Enumeration. Интерфейс Enumeration объявляет два метода:

public abstract boolean hasMoreElements()

Возвращает true, если перебор элементов перечисления еще не закончен. Метод может многократно вызываться между последовательными  вызовами nextElement.

public abstract Object nextElement()

Возвращает следующий элемент перечисления. Вызовы этого метода осуществляют последовательный  перебор всех элементов. Если следующего элемента не существует, возбуждается исключение NoSuchElemen tException.

Приведем типичный цикл, в котором Enumeration используется для перебора элементов класса-коллекции,  в данном случае — элементов хеш-таблицы:

Enumeration e = table.elements();

while (e.hasMoreElements())

doSomethingWith(e.nextElement());

Контракт Enumeration не гарантирует фиксации исходного состояния (snapshot

guarantee). Другими словами, если содержимое коллекции изменяется во время итерации, это может отразиться на значениях, возвращаемых методами. Например, если в реализации nextElement используется содержимое исходной коллекции, то удаление объектов из списка во время перебора может иметь разрушительные последствия. Если

бы исходное состояние было зафиксировано, то работа с объектами осуществлялась бы в

том виде, в каком они находились на момент создания Enumeration. Вы можете рассчитывать на фиксацию исходного состояния лишь в том случае, если метод, возвращающий объект Enumeration, явно это гарантирует.

12.3. Реализация интерфейса

Enumeration

При разработке новых классов-коллекций  может возникнуть необходимость в собственной реализации Enumeration. Приведенный выше класс Which Chars фактически представляет собой коллекцию для работы с набором символов исходной строки. Следующий класс реализует интерфейс Enumeration для того, чтобы возвращать символы, представленные объектом BitSet в WhichChars:

class EnumerateWhichChars implements Enumeration {

private BitSet bits;

private int pos;      // следующая проверяемая позиция

private int setSize;  // количество бит (для оптимизации)

EnumerateWhichChars(BitSet whichBits) {

bits = whichBits;

setSize = whichBits.size();

pos = 0;

}

public boolean hasMoreElements() {

while (pos << setSize && !bits.get(pos))

pos++;

return (pos << setSize);

}

public Object nextElement() {

if (hasMoreElements())

return new Character((char)pos++);

else

}

}

return null;

Класс перебирает биты, входящие в BitSet, и возвращает объекты Character со значениями символов, которым соответствуют установленные биты в объекте BitSet. Метод hasMoreElements перемещает текущую позицию к следующему возвращаемому элементу. Он написан так, чтобы его можно было многократно использовать для каждого вызова nextElement.

Теперь в класс WhichChars необходимо включить метод, который возвращает объект-

перечисление:

public Enumeration characters() {

return new EnumeratrWhichChars(used);

}

Обратите внимание: метод characters возвращает объект класса Enumeration, а не EnumerateWhichChars. Класс EnumerateWhichChars не предназначен для открытого использования, поэтому реализацию перечисления можно скрыть. Если только вы не захотите возвращать объект-перечисление с новыми открытыми возможностями, следует скрывать тип объекта, чтобы оставить для себя возможность изменить его реализацию по своему усмотрению.

Источник: Арнольд К., Гослинг Д. – Язык программирования Java (1997)

По теме:

  • Комментарии