Arhn - архитектура программирования

java.util.BitSet set() не работает должным образом

Я упускаю что-то болезненно очевидное? Или просто никто в мире не использует java.util.BitSet?

Следующий тест не проходит:

@Test
public void testBitSet() throws Exception {
    BitSet b = new BitSet();
    b.set(0, true);
    b.set(1, false);
    assertEquals(2, b.length());
}

Мне действительно неясно, почему я не получаю BitSet длиной 2 и значением 10. Я заглянул в источник для java.util.BitSet, и при случайном осмотре, кажется, не удается провести достаточное различие между бит это было установлено как false и бит, который никогда не устанавливался ни в какое значение...

(Обратите внимание, что явное задание размера BitSet в конструкторе не имеет никакого эффекта, например:

BitSet b = new BitSet(2);

  • Или просто никто в мире не использует java.util.BitSet? ... да, да, потяни другой - на нем колокольчики! 18.05.2010
  • @Стивен, какой еще? ;-) 19.05.2010

Ответы:


1

Люди используют BitSet; однако они используют его для чего-то другого, кроме того, что вы намереваетесь. Вероятно, лучше всего думать о BitSet как об очень компактной, эффективной по памяти форме Set<Integer>, которая имеет особое свойство: вы не можете помещать в нее отрицательные числа.

С BitSet очень часто используют их в шаблоне

for (int id = set.nextSetBit(0); id >= 0; id = set.nextSetBit(id + 1)) {
  // do stuff to a set index
}

после того, как вы сделаете что-то, чтобы заполнить их. Это эквивалентно перебору элементов массива Set.

18.05.2010
  • Хорошее объяснение. По сути, кажется, что BitSet не совсем подходит для представления битового поля фиксированной длины (или битового массива). 19.05.2010
  • Что ж, для фиксированной длины, если вы не полагаетесь на BitSet, чтобы поддерживать длину для вас, все в порядке. Если вы хотите, чтобы BitSet обрабатывал длину за вас, вы будете разочарованы. 19.05.2010

  • 2

    Самый высокий установленный бит (например, установленный на 1) равен биту 0. Таким образом, длина должна быть равна 1.

    См. JavaDoc для получения информации о длине:

    общедоступная целая длина()

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

    Возможно, вы ищете размер хотя возможно, что это может быть больше, чем два, если биты распределены с определенным разрешением (скажем, 16-битные границы)?

    18.05.2010
  • ZZ, я почистил его, чтобы убедиться, что он понятен (и поставил +1), надеюсь, вы не возражаете. Учитывая, что я изначально неправильно понял set как установленный на что угодно, у простых смертных тоже может быть такая проблема :-) 18.05.2010

  • 3

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

    import java.util.BitSet;
    
    /**
     * Variation of BitSet which does NOT interpret the highest bit synonymous with
     * its length.
     *
     * @author [email protected]
     */
    public class FixedBitSet extends BitSet{
    
        int fixedLength;
    
        public FixedBitSet(int fixedLength){
            super(fixedLength);
            this.fixedLength = fixedLength;
        }
    
        @Override
        public int length() {
            return fixedLength;
        }
    }
    
    20.09.2010

    4

    Учитывая, что набор битов поддерживается long[], минимальный размер равен 64 (поскольку 1 long равен 64 битам). Размер увеличивается на кратное 64, и по какой-то причине они не сохранили количество битов, которое вы намеревались представить, когда используете конструктор, который принимает int.

    28.08.2010

    5

    // Абхай Дандекар

    import java.util.BitSet;
    
    public class TestBitSet {
    
        public static void main(String[] args) {
    
            BitSet bitSet = new BitSet();
            System.out.println("State 0 : " + bitSet.size() + " : " + bitSet.length() );
    
            bitSet.set(0, true);
            bitSet.set(1, true);
            System.out.println("State 1 : " + bitSet.size() + " : " + bitSet.length() );
    
            bitSet.set(2, false);
            bitSet.set(3, false);
            System.out.println("State 2 : " + bitSet.size() + " : " + bitSet.length() );
    
            bitSet.set(4, true);
            System.out.println("State 3 : " + bitSet.size() + " : " + bitSet.length() );
    
        }
    }
    

    Простая Java-программа, показывающая, что происходит внутри. Некоторые моменты, на которые следует обратить внимание:

    1. BitSet поддерживается длинным

    2. Все значения по умолчанию ложны

    3. Возвращая длину, он возвращает index+1 самого высокого «истинного» значения в наборе.

    Вывод ниже должен быть в состоянии объяснить себя:

    State 0 : 64 : 0
    
    State 1 : 64 : 2
    
    State 2 : 64 : 2
    
    State 3 : 64 : 5
    

    Итак, в заключение:

    1. Не используйте длину, чтобы сделать вывод о количестве измененных битов.

    2. Может использоваться в таких сценариях, как фильтры Блума. Подробнее о фильтрах Блума можно погуглить .. ;)

    Надеюсь это поможет

    С уважением,

    Абхай Дандекар

    18.04.2014

    6

    Хороший Каспер! Ваше небольшое улучшение действительно должно было присутствовать в исходном java-деф BitSet! Я также предлагаю это (append() и concat() полезны для различных целей)

    import java.util.BitSet;
    
    public class fixBitSet extends BitSet {
    
      public int fsize = 0;
    
      public void set(int k, boolean value) {
        if (k >= fsize)
          fsize = k + 1;
        super.set(k, value);
      }
    
      public void append(fixBitSet bs) {
        for (int k = 0; k < bs.fsize; k++)
          super.set(fsize + k, bs.get(k));
        fsize += bs.fsize;
      }
    
      public static fixBitSet concat(fixBitSet[] vbs) {
        final fixBitSet bs = new fixBitSet();
        for (fixBitSet xbs : vbs)
          bs.append(xbs);
        return (bs);
      }
    
    }
    
    22.01.2014
    Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..