views:

254

answers:

3

Hi guys i've never written a comparator b4 and im having a real problem. I've created a hashtable.

Hashtable <String, Objects> ht;

Could someone show how you'd write a comparator for a Hashtable? the examples i've seen overide equals and everything but i simply dont have a clue. The code below is not mine but an example i found, the key thing in hashtables means i cant do it like this i guess.

 public class Comparator implements Comparable<Name> {
        private final String firstName, lastName;

        public void Name(String firstName, String lastName) {
            if (firstName == null || lastName == null)
                throw new NullPointerException();
        this.firstName = firstName;
            this.lastName = lastName;
        }

        public String firstName() { return firstName; }
        public String lastName()  { return lastName;  }

        public boolean equals(Object o) {
            if (!(o instanceof Name))
                return false;
            Name n = (Name)o;
            return n.firstName.equals(firstName) &&
                   n.lastName.equals(lastName);
        }

        public int hashCode() {
            return 31*firstName.hashCode() + lastName.hashCode();
        }

        public String toString() {
        return firstName + " " + lastName;
        }

        public int compareTo(Name n) {
            int lastCmp = lastName.compareTo(n.lastName);
            return (lastCmp != 0 ? lastCmp :
                    firstName.compareTo(n.firstName));
        }
    }
+1  A: 

A Comparator will tell you which of two items is larger. If this has meaning for your HashTable, only you can say what the meaning is. It would be very unusual to want to compare two HashTables in this way.

Carl Manaster
So you're saying i shouldnt have done a hash table? would something like a treeset be more suitable? basically i have a collection of data (currently in a hash table) that i want to arrange alphabetically
A: 

Comparators are used to sort a list. A Hashtable (note the case) is not ordered by its elements. You can order a table by iterating over its keys (in the case you'd want to order on its keys, I presume) and put them in a List. The next thing to do is to sort the List and iterate over the List, and use a get out of the Hashtable to get its associated value.

Here is an example (using HashMap, since it's more integrated with the rest of the Java Collections. A HashMap is essentially the same as Hashtable.):

public static void main(String... arg) {
    HashMap<String, Object> x = new HashMap<String, Object>();
    x.put("second", " ordered!");
    x.put("first", "Correctly");

    LinkedList<String> keys = new LinkedList<String>();
    for(final String f : x.keySet()) {
        keys.add(f);
    }
    Collections.sort(keys, new Comparator<String>() {
        public int compare(String first, String second) {
            // return -1 is "first <  second"
            // return 1  is "first >  second"
            // return 0  is "first == second"
            return first.compareTo(second);
        }
    });

    for(final String f : keys) {
        System.out.print(x.get(f));
    }
    System.out.println();
}

The order of the list keys is sorted by the anonymous Comparator class. It will sort alphabetically, as is the default for Strings. You can use your own key object, like you mentioned. If you don't implement Comparator in this key object, then you can supply, as in the above example. Else you can use the default Comparator by calling:

Collections.sort(keys);

Which will use the classes implementation of Comparator. If it does not implement Comparator, then it will throw an exception (since it will cast to a Comparator)

Pindatjuh
Hi, thats fantastic, so you're saying to use Hashmap instead of Hashtable. I dont understand why you are using a linked list though?
Because neither `HashMap` (note the case of the M) nor `Hashtable` (small t), are "ordered". Thus their elements are in a semi-random order stored, to enhance performance. I use a `LinkedList` because I use a lot of `.add(f);`, and `LinkedList` is optimized for append/removal. Then the `List` is ordered using `Collections.sort`. A list has internal representation of order, it is "ordered", and thus the order of the keys of the `HashMap` is stored in the `List`. Iterating over the `List` will give the keys in correct order.
Pindatjuh
A Map (HashMap) does not do ordering of its elements. The order of the keys is determined by the hash value of the key object, so you can't sort a HashMap (or Hashtable). The point of the LinkedList is to order the keys of your HashMap alphabetically, you can then use this ordered list to get at the associated values. Are you sure a Hashtable is really what you want to be using?
DaveJohnston
If you want to order by the keys, why not use a TreeMap?Map sortedMap = new TreeMap(comparatorInstance);sortedMap.putAll(hashMap);Or better yet, use a tree map from the beginning.
ILMTitan
+1  A: 

That's not a Comparator class. That's a Name class that implements Comparable.

Hashtable and Hashmap don't use either Comparator or Comparable. If you want sorted keys use a TreeMap.

EJP