2

When I add some items into a Java Hashtable, their order is different to that of a .NET Hashtable. Is there any way I can make sure the .NET Hashtable will have the same order as a Java Hashtable?


I'm trying to port some Java code to C#. The Java code uses a Hashtable to keep track of some data. When I check to see the order the data is retrieved when I iterate through either the Java Hashtable or the .NET Hashtable (via an Enumerator), each one consistently has the same data, in the same order ... but each code based has a different order.

Is there any way I can make it so that the .NET Hashtable data is in the same order as the Java Hashtable?

I understand that Hashtable do not handling ordering - so I feel like there's nothing that can be done. I also cannot change the datatype in the Java code from .. say .. a Hashtable to something else.

Here's some same data to illustrate my situation.

Data, added sequential for either code base :-

  1. num | someData
  2. pagenum | someData
  3. x | someData
  4. top | someData

Java Code:

private Hashtable identifiers = new Hashtable();
...
identifiers.put(symbol, identifier);

Java output via iteration over an enumerator:

alt text

.NET code:

private Hashtable Identifiers = new Hashtable();
...
Identifiers.Add(symbol, identifier);

.NET output via iteration over an enumerator.

alt text

Any ideas or suggestions?

Pure.Krome
  • 84,693
  • 113
  • 396
  • 647
  • 2
    Hash tables define no order on their items and neither Java nor .NET guarantee one. – Joey Jan 07 '11 at 00:06
  • 1
    Are you certain order matters in porting? – Nikita Rybak Jan 07 '11 at 00:07
  • @Nikita Rybak - unfortunatly, it's crucial. The Java code iterates through each key and replaces the data value with a single character. eg. first data value 'x' becomes 'a'. 2nd data value 'pagenum' becomes 'b'. In the c# code, 'pagenum' is 'c' and 'x' is 'd'. :( Code still works, it's just that the results are no *identical*, now. – Pure.Krome Jan 07 '11 at 00:14

7 Answers7

9

Unfortunately, short of changing the type of the collection there's really no way around this. Hashtables don't guarantee order (as you mentioned in your post).

It all boils down to the following:

If order matters, a Hashtable is the wrong data structure.

Justin Niessner
  • 242,243
  • 40
  • 408
  • 536
3

You cannot change this order short of extracting the keys and sorting them in some way (or using an ordered dictionary). The iteration orders of either of the hashtable implementations you are using are not specified, and therefore relying on a specific order means your code is broken. The iteration order in Java is not even guaranteed to remain the same in future versions of the JDK.

cdhowie
  • 158,093
  • 24
  • 286
  • 300
  • Actually you can if you override hashing algorithm ;) But of course that doesn't solve the original problem. – Schultz9999 Jan 07 '11 at 00:12
  • 2
    Schultz999: No you can't, since there is no guaranteed relationship between the hash code and the "order" of a Hashtable. – jarnbjo Jan 07 '11 at 01:57
2

The order in the generic hashtable is unpredictable. That's what you are experiencing. If you are trying to run comparison tests and if you need specific order, you have to use ordered maps on BOTH ends. Otherwise there isn't hardly a way to predict the output.

Schultz9999
  • 8,717
  • 8
  • 48
  • 87
1

I agree with other answers, but still, Hashtable is deprecated. You should always use a generic Dictionary class. There is also a SortedDictionary, class name says all. you can reverse or sort it's content, take a look here Reverse Sorted Dictionary in .NET

Community
  • 1
  • 1
Davita
  • 8,928
  • 14
  • 67
  • 119
  • what's the equivalent of a SortedDictionary, in Java? A SortedMap ? – Pure.Krome Jan 07 '11 at 00:17
  • Hashtable is not *deprecated*. There is a better alternative, but it isn't deprecated. Although most of the time you want Dictionary`2, there's nothing wrong with using an Hashtable when one fits the bill. It's just a Dictionary. Also, how do you know this isn't .NET 1.0 or 1.1? Dictionary wasn't around back then. – R. Martinho Fernandes Jan 07 '11 at 00:21
1

You could use a LinkedHashMap in Java and Recursion Software makes one available for C# as per this post.

I have not tried this solution.

Community
  • 1
  • 1
Romain Hippeau
  • 24,113
  • 5
  • 60
  • 79
1

It's a terrible solution, but according to your description you have no other option.

You can take sources of Java Hastable class and port them to C#. Strip down everything unnecessary, like iterators and keySet, equals, and you will have pretty small class (few dozen lines I'd expect). Converting it to C# should be trivial.

Naturally, you shouldn't use this new class for anything other than Java compatibility. And filing a bug with original application vendor might be nice too :)

Nikita Rybak
  • 67,365
  • 22
  • 157
  • 181
0

You could try to implement (in .NET) your own IHashCodeProvider and IComparer and pass those to the Hashtable constructor. From the example you posted it appears that the entries are sorted on the key ascending (.NET) and descending (Java) order so you'd need a comparer that inverts the order.

Serguei
  • 2,910
  • 3
  • 24
  • 34