2015-05-03 4 views
1

Я пишу программу java с использованием HashTable, и мне трудно использовать ее. У меня есть хэш-таблицу объекта, между инициализацией и чтения, объекты изменения значенийhashtable, который меняет значение самостоятельно

Так как кусок кода является более понятным, чем большой пункт, здесь:

class localDictionnary { 
     private Map<Entries, Symbol> dictionnary; 
     public LocalDictionnary() {  
      this.dictionnary = new Hashtable<Entre, Symbole>(); 
     } 
     public void add(Entries e, Symbol s) { 
      dictionnary.put(e, s); 
     } 
     public void check() { 
      int displacement = 0; 
      for(Entry<Entries, Symbol> e : this.dictionnary.entrySet()){ 
       e.getValue().setDisplacement(displacement); 
       displacement += e.getValue().getSize(); 
       System.out.print(e.getValue().getDisplacement() + " "); 
      } 
      System.out.println(""); 
      for(Entry<Entries, Symbol> e : this.dictionnary.entrySet()) 
       System.out.print(e.getValue().getDisplacement() + " "); 
     } 
    } 

натянутых программы:

0 4 8 12 16 20 24 28 32 36 
8 8 32 16 36 28 28 32 36 0 

величина смещения не совпадают между первым и вторым вызовом Println, где он, очевидно, следует, даже если порядок изменился

Проблема не из-за того, как HashTable сортирует элементы, а программа полностью последовательна, поэтому нет другой нити, которая ударит каждую вещь вниз ...

Я не являюсь этой новой программой написания java, но должен сказать, , это первый раз, когда я использую Hashtables ...

Большое спасибо за вашу помощь = P

PS: Я не родной английский, так что простите меня за мои ошибки

Edit:

вот кусок кода, который добавит <key, value> в HashMap, это код Java-чашка:

DECL_CHAMP ::=  STATUS:s TYPE:t ID:id 
       {: 
        SymbolTable.add(new Entries(id), new Symbol(s, t)); 
       :} 
     ; 
STATUS  ::=  PUBLIC 
       {: 
        RESULT = Symbole.Statue.PUBLIC; 
       :} 
     |  PRIVATE 
       {: 
        RESULT = Symbole.Statue.PRIVATE; 
       :} 
     ; 
TYPE  ::=  INTEGER 
       {: 
        RESULT = Symbole.Type.INTEGER; 
       :} 
     ; 

Edit: идентичность обоих печатных заявлений:

первая печать:
1271698539 1680090029
10643000 635758299
1458587468 635758299
953744171 1680090029
760340789 1519941073
1331632846 1826157335
390046421 1390107103
1055484408 1390107103
1311521036 1680090029
961899244 1826157335

второй печати:
1271698539 1680090029
10643000 635758299
1458587468 635758299
953744171 1680090029
760340789 1519941073
1331632846 1826157335
390046421 1390107103
1055484408 1390107103
1311521036 1680090029
961899244 1826157335

+0

Прежде всего, не используйте «Hashtable», используйте «HashMap». Он не синхронизирован и работает быстрее. 'Hashtable' устарел. –

+1

Следующий вопрос, возможно, у вас есть тот же символ «Символ», отображаемый более чем на «Записи»? –

+0

Я впервые использовал HashMap, но была та же проблема, это был просто тест на использование HashTable – nicoptere

ответ

2

Из комментариев:

да у меня есть, на самом деле, есть несколько символов, которые могут быть равны

Быстрая демонстрация проблемы:

public static void main(String[] args) throws Exception { 
    final AtomicInteger a = new AtomicInteger(0); 
    System.out.printf("a:%s%n",a); 
    final AtomicInteger b = a; 
    System.out.printf("a:%s.b:%s%n", a, b); 
    a.set(10); 
    System.out.printf("a:%s.b:%s%n", a, b); 
    b.set(5); 
    System.out.printf("a:%s.b:%s%n", a, b); 
} 

Выход:

a:0 
a:0.b:0 
a:10.b:10 
a:5.b:5 

Итак, что здесь происходит? AtomicInteger изменен. И Java передает ссылки по значению, поэтому, когда мы назначаем b = a, мы делаем копию ссылки на AtomicInteger, что a ссылки на новую ссылку b.

Так что когда мы меняем a we также изменение b.

Как это влияет на вас?Ну все, что нам нужно сделать, это немного изменить пример, чтобы показать такое же поведение:

final Map<String, AtomicInteger> map = new HashMap<>(); 
final AtomicInteger i = new AtomicInteger(0); 
map.put("aa", i); 
map.put("bbbbb", i); 
map.forEach((k, v) -> { 
    v.set(k.length()); 
    System.out.printf(" %s ", v); 
}); 
System.out.println(); 
map.values().forEach(v -> System.out.printf(" %s ", v)); 
System.out.println(); 

Выход:

2 5 
5 5 

Таким образом, когда мы изменим значение отображенный на bbbbb, поскольку тот же объект также отображается к aa мы также меняем это значение.

TL; вам необходимо понять, как работают ссылки.

P.S. A Hashtable или HashMap имеет заказать. Вам нужно использовать LinkedHashMap или TreeMap, если вы хотите зациклиться на Map и полагаться на порядок итераций - в противном случае заказ не определен, но он также может быть изменен произвольно.

+0

Дело в том, что объекты 'Symbol' равны, но существуют разные объекты. – nicoptere

+0

@nicoptere не похоже на это из вашего примера ... Я вижу повторяющиеся числа, которые подразумевают, что, например, '[2] == [7]'. –

+0

Я понимаю, что вы имеете в виду, но каждый раз, когда я добавляю новую карту к карте, я создаю новый «Записи» и новый символ «Символ» – nicoptere