Странное поведение счетчика HashMap

У меня есть этот код, который применяет счетчик к каждому элементу в списке. Когда элемент достигает определенного номера, он перемещается из jList3 в jList 1.

public Map<Object, Integer> buttonMap = new HashMap<Object, Integer>();
    private void jButton5ActionPerformed(java.awt.event.ActionEvent evt) {  

    Integer counter = null;
    int[] selection = jList3.getSelectedIndices();
     for (int i = 0; i < selection.length; i++){
        Object selString = jList3.getModel().getElementAt(selection[i]);
       counter = buttonMap.get(selString);      
        if(counter == null ) {           
            buttonMap.put(selString, new Integer(1));     
        }                                                                                                      
        else {
        buttonMap.put(selString, new Integer(counter.intValue() + 1)); 
        }           
        System.out.println(selString + " has been clicked " + buttonMap.get(selString) + " times.");                                      

       try{
        if (counter == 4){                          
           listModel2.removeElement(selString);
            listModel.addElement(selString);                             
        }
       }
        catch (NullPointerException npe1) {
        npe1.getMessage();
              }                                                                  
        }                                                   
  } 

Поведение находится в разделе if counter == 4.

Он работает нормально, но вот странная часть, которую мне нужно понять.

Если я подсчитываю два элемента одновременно, и они оба достигают числа, которое перемещает их одним и тем же нажатием кнопки.

- Он перемещает 1 из предметов

- это не считается с другим

-Вместо этого он добавляет +1 к счетчику невыделенного предмета.

Пример:

Я рассчитываю на элементы списка 1 и 2, они оба достигают максимального числа, 1 перемещается, 2 остается на месте (количество не увеличивается), а элемент 3 получает +1 к счетчику.


person sealz    schedule 22.07.2011    source источник
comment
Как реализована ваша логика подсчета? У вас есть несколько потоков? Потому что код, который вы показали выше, не является потокобезопасным.   -  person Perception    schedule 22.07.2011
comment
почему у всех один и тот же ключ?   -  person Hunter McMillen    schedule 22.07.2011
comment
@Perception добавил весь код, так что простая потоковая обработка исправит это?   -  person sealz    schedule 22.07.2011
comment
@harper89 - хорошо, хорошо. Быстрый вопрос: listModel2 такой же, как jList3.getModel()?   -  person Perception    schedule 22.07.2011
comment
@восприятие Да. Я предполагаю, что мой большой вопрос заключается в том, что заставляет +1 что-то, что не выделено? И всем извините за название, это просто то, что я делаю на стороне, поэтому я делаю то, что хочу :)   -  person sealz    schedule 22.07.2011
comment
@ harper89 - похоже, Морис уже опубликовал ответ. Вы можете увидеть мой также ниже!   -  person Perception    schedule 22.07.2011


Ответы (2)


Когда вы удаляете элемент из jList3, последующие элементы сдвигаются. Я бы отсортировал массив выбора и отсканировал его в обратном порядке.

...
int[] selection = jList3.getSelectedIndices();
Arrays.sort(selection);
for (int i = selection.length; --i >= 0; ){
...

ОБНОВЛЕНИЕ: сортировка не требуется, поскольку массив, возвращаемый функцией getSelectedIndices(), уже

person Maurice Perry    schedule 22.07.2011
comment
аааа, я вижу, если я добавлю элемент, а затем удалю, я не получу странное голосование, просто исключение за пределы - person sealz; 22.07.2011
comment
@ Морис, если бы я запускал каждый элемент в отдельной теме? Это также решит проблему или это слишком? - person sealz; 22.07.2011
comment
j/w еще раз спасибо за то, что они смещаются, что решило путаницу - person sealz; 22.07.2011

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

...
    System.out.println(selString + " has been clicked " + buttonMap.get(selString) + " times.");

    if (counter == 4) {
        listModel.addElement(selString);
    }
}

for(Object o : listModel) {
    listModel2.removeElement(o);
}
person Perception    schedule 22.07.2011