I have declared and initialized these hashtable:
Hashtable<String,Integer> ht = new Hashtable<String,Integer>();
ht.put("due", 2);
ht.put("tre", 3);
ht.put("uno", 1);
Hashtable<String,Integer> ht = new Hashtable<String,Integer>();
ht.put("dodici", 12);
ht.put("tredici",13);
ht.put("nove", 9);
ht.put("dieci", 10);
I want to extract values from hashtable using JDI to compare pairs of elements, I have a method that has as parameters ArrayReference s0, s1 ArrayReference, Parameter parameter1, parameter2 Parameter:
if(parameter1.getType().name().equals("java.util.Hashtable")){
System.out.println(" - Hashtable/HashMap - ");
ObjectReference o = (ObjectReference) parameter1.getValue();
ObjectReference o2 = (ObjectReference) parameter2.getValue();
ClassType ct = (ClassType) o.type();
System.out.println("ct "+ ct.allFields());
Value x=o.getValue(ct.fieldByName("table") ); // hashtable.Entry
Value y=o2.getValue(ct.fieldByName("table"));
System.out.println(y.toString());
System.out.println(o.getValue(ct.fieldByName("table")));
Parameter p1 =new Parameter(ct.fieldByName("table").name(),x.type(),x);
Parameter p2 =new Parameter(ct.fieldByName("table").name(),y.type(),y);
if(p1 != null && p2!=null)
distObject = getDistanceCollections(p1,p2);
}
...
else if(s0.getValue(i-1).type().name().equals("java.util.Hashtable$Entry")){
ObjectReference ox = (ObjectReference) s0.getValue(i-1);
ObjectReference oy = (ObjectReference) s1.getValue(j-1);
ClassType ct = (ClassType) ox.type();
ClassType ct2 = (ClassType) oy.type();
System.out.println("ct field Entry: "+ct + ct.allFields());
Value keyx= ox.getValue(ct.fieldByName("key"));
Value valuex= ox.getValue(ct.fieldByName("value"));
Value keyy= oy.getValue(ct2.fieldByName("key"));
Value valuey= oy.getValue(ct2.fieldByName("value"));
if(s0.getValue(i-1).type().name().equals("java.util.Hashtable$Entry")){
Parameter p1 =new Parameter(ct.fieldByName("value").name(),valuex.type(),valuex);
Parameter p2 =new Parameter(ct2.fieldByName("value").name(),valuey.type(),valuey);
if(p1 != null && p2!=null)
match = getDistanceCollections(p1,p2);
}
...
for (int j = 1; j < len1; j++) {
System.out.println( s1.getValue(j-1));
}
for (int i = 1; i < len0; i++)
System.out.println( s0.getValue(i-1));
...
else if(typeName.equals("java.lang.Integer")
||typeName.equals("java.lang.Boolean")
||typeName.equals("java.lang.Double")
||typeName.equals("java.lang.Float")
||typeName.equals("java.lang.Byte")
||typeName.equals("java.lang.Long")
||typeName.equals("java.lang.Short")
||typeName.equals("java.lang.Character")){
Value x=o.getValue(ct.fieldByName("value")); //Integer.value
Value y=o2.getValue(ct2.fieldByName("value"));
System.out.println("Valori: x = "+x+" y ="+y);
distObject = (double) getDistancePrimitive(x.type(), x,y.type(),y);
double matchInternal= distObject;
...
The problem is that during the extraction of the values I have the loss of an element. This element is not in memory. Java version: 1.8.0_40
Output: https://i.stack.imgur.com/hEgsB.gif
Does anyone know how to fix?
An Hashtable object store the pair key-value in an table based on the hash value of the key. If two differents keys have the same hash value, the second value is stored as next value for that hash value.
You can see a graphical example here: hashTable
When you work with JDI and as in your example you have "java.util.Hashtable" you must extract the field table(how you did) and then you will obtain a "java.util.Hashtable$Entry" classType.
This type has 4 field java.util.Hashtable$Entry.hash, java.util.Hashtable$Entry.key, java.util.Hashtable$Entry.value, java.util.Hashtable$Entry.next, now you work only on key and value, and you lose a value because you don't consider the next field.