自行更改值的哈希表
hashtable that change value by itself
我正在使用 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-cup代码:
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
来自评论:
yes i have, actually, there are several Symbol that can be equal
问题的快速演示:
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:您需要了解引用的工作原理。
P.S。 Hashtable
或 HashMap
没有顺序 。如果您想遍历 Map
并依赖迭代顺序,则需要使用 LinkedHashMap
或 TreeMap
- 否则顺序未定义,但它也可以任意更改.
我正在使用 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-cup代码:
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
来自评论:
yes i have, actually, there are several Symbol that can be equal
问题的快速演示:
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:您需要了解引用的工作原理。
P.S。 Hashtable
或 HashMap
没有顺序 。如果您想遍历 Map
并依赖迭代顺序,则需要使用 LinkedHashMap
或 TreeMap
- 否则顺序未定义,但它也可以任意更改.