我正在使用HashTable编写Java程序,但很难使用它。我有一个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:我不是英语,所以请原谅我的错误

编辑:

这是在HashMap中添加<key, value>的代码,这是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;
                :}
        ;


编辑:
这两个打印语句的标识:

第一次打印:
    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

最佳答案

从评论:


  是的,我有,实际上,有几个符号可以相等


问题的快速演示:

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时,我们也会更改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; DR:您需要了解引用的工作方式。

附言HashtableHashMap没有顺序。如果要循环遍历LinkedHashMap并依赖迭代顺序,则需要使用TreeMapMap-否则该顺序未定义,但它也可以任意更改。

关于java - 自己改变值(value)的哈希表,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30019902/

10-12 17:26