Sorting a HashMap

Discussions

General J2EE: Sorting a HashMap

  1. Sorting a HashMap (7 messages)

    Whats the simplest and efficient way to sort a hashmap and both display the results and reassign the sorted collection back to a HashMap object?

    I have a hashmap keyed with integers which stores a simple object with an attribute of score

    I've tried the following but it doesnt seem to work ?

    public class TestDie2 {


      public static void main( String args[] )
      {

    HashMap map = new HashMap();
    Player player;

    //Create objects within array
    for( int i = 0; i<5; i++ )
    {
             map.put(new Integer(i), new Player("Paul" + i));
    player = (Player) map.get( new Integer(i) );

    for ( int turn = 0; turn< 10; turn++ ) // loop 10 times
    player.taketurn();

    //int value = d1.getFaceValue();
    System.out.println("Player " + (i+1) + " Score is " + player.getScore() ); // print to console
    }

    //Now print the elements in the HashMap
    System.out.println(map);

    //Print the Keys
    Set set = map.keySet();
    Iterator it = set.iterator();
    while (it.hasNext())
       System.out.println(it.next());
      
       //Sort using a TreeSet ??
       Iterator tit = new TreeSet (map.keySet()).iterator();
    while (it.hasNext())
    {
       // Now, you're reading the key objects in
    // the natural sort order...
    Player player_sort = (Player) tit.next();
    // Refer to the original Hashtable for the
    // corresponding value...
    Player player_sort2 = (Player) map.get(player_sort);
    System.out.println("Player Score is " + player_sort2.getScore());
    }

    //Sort using Collections ??
    ArrayList keys = new ArrayList();
    keys.addAll(map.keySet());
    Collections.sort(keys);
    Iterator it2 = keys.iterator();
    while (it2.hasNext())
       System.out.println(it2.next());


    }

    }

    Threaded Messages (7)

  2. Sorting a HashMap[ Go to top ]

    I should of course mention that Id like to sort the map on the score attribute of the value object NOT on the key obviously (as id just use a treemap)
  3. Sorting a HashMap[ Go to top ]

    Will the player always be sorted on their score attribute?

    If so, you might want to make your Player value object implement the Comparable interface. You implement the compareTo(Object obj) method, as so:

    public class Player implements Comparable {

    ...
    ...

    public int compareTo(Object obj) {
    Player comparePlayer = (Player)obj;

    if (this.getPlayerScore() > comparePlayer.getPlayerScore()) {
    return -1;
    } else if (this.getPlayerScore() < comparePlayer.getPlayerScore()) {
    return 1;
    } else {
    return 0;
    }

    }

    }

    This will mean that if a List of Player objects is sorted, the Players will be sorted by their score in descending order.

    In your method, you can then sort the value objects in your map by the following code:


    List playerList = new ArrayList();
    playerList.addAll(map.values());

    Collections.sort(playerList);

    Iterator iter = playerList.iterator();

    while(iter.hasNext()) {
    System.out.println(iter.next());
    }


    Hope that helps!
  4. Sorting a HashMap[ Go to top ]

    Of course, if I actually read your question in full, you sound like you want a permanently sorted hash map. If this is the case you could use the TreeMap, but rather than using an arbitrary int value as the key, you create a little key object for your Player value objects. This key implements the comparable interface (rather than the value object), which means that your keys will always be sorted, when accessing the map.

    For example,

    public class PlayerScoreKey implements Comparable {

    private Player player;

    public PlayerScoreKey (Player player) {
    this.player = player;
    }

    public int getPlayerScore() {
    return player.getPlayerScore();
    }

    public int compareTo(Object obj) {
    PlayerScoreKey compareKey = (PlayerScoreKey)obj;

    if (this.getPlayerScore() > compareKey.getPlayerScore()) {
    return -1;
    } else if (this.getPlayerScore() < compareKey.getPlayerScore()) {
    return 1;
    } else {
    return 0;
    }
    }

    }

    To access this map, in a sorted fashion, you would do the following:

    Iterator keyIter = map.keySet().iterator();

    //Output players, sorted by player score
    while(keyIter.hasNext()) {
       System.out.println(map.get(keyIter.next());
    }



    Note that you need to have the key linked to the Player value object in some way (you can't just create a key with the Player's score), as otherwise if the Player value object's score is altered in any way, the Player's key will not be updated automatically.

    Anyway, I hope that actually answers your question this time! If I might ask, why are you using a HashMap at all? You seem to be loading the HashMap using arbitrary keys, which doesn't make much sense :)
  5. Sorting a HashMap[ Go to top ]

    Im really just playing around with the collections API, trying to get a handle on where it could best be used

    I like your idea of using an object as the key, rather than just an integer ( or DB primary key). In that way I can add the score of the player to that keying object and although it is replicated in both key and value I can at least then sort it. What I struggled with initially with was the concept that the comparator sorts on the key NOT on the value, thus by giving the key the value it needs to sort I can maintain it

    I also like the TreeMap idea. Creating one with a comparator ( passed in the constructor which sorts this key object by score ) then if I understand correctly the TreeMap itself will ensure the map remains sorted when the Put method is used. Not sure how performance efficient this would be though ?
  6. Sorting a HashMap[ Go to top ]

    To be quite honest, if you're just looking to have your value objects sorted, then placing your value objects in a List will be sufficient.

    Performance wise, Maps come into there own when you have a large number of objects and you wish to retrieve a specific object by a key. This is much better than iterating through a List, making comparisons until you have the correct one.
  7. Hashmap tutorial[ Go to top ]

    Please see hashmap tutorial and example at below link http://www.developerzone.biz/index.php?option=com_content&task=view&id=90&Itemid=36
  8. Re: Hashmap tutorial[ Go to top ]

    Try this code import java.util.*; public class TestSort { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub TestSort tt=new TestSort(); tt.getSort(); } public void getSort(){ SortedHashMap map = new SortedHashMap(); Player p=new Player(); p.setName("Fred"); map.put(p, "Fred"); p=new Player(); p.setName("Bill"); map.put(p, "Bill"); p=new Player(); p.setName("Harry"); map.put(p, "Harry"); p=new Player(); p.setName("Jim"); map.put(p, "Jim"); p=new Player(); p.setName("Dave"); map.put(p, "Dave"); p=new Player(); p.setName("Alan"); map.put(p, "Alan"); /*map.put("444", "Alan"); map.put("555", "Dave"); map.put("666", "Jim"); map.put("111", "Fred"); map.put("222", "Bill"); map.put("333", "Harry");*/ System.out.println("Sort by value (name):"); Iterator iter = map.iterator(); while (iter.hasNext()) { Player pp=(Player)iter.next(); System.out.println(pp.getName()); } /*System.out.println("\nRetrieve value (name) by index:"); System.out.println("444 = " + map.get("444")); System.out.println("222 = " + map.get("222")); System.out.println("111 = " + map.get("111")); System.out.println("555 = " + map.get("555")); System.out.println("333 = " + map.get("333")); System.out.println("666 = " + map.get("666")); */ } class SortedHashMap extends HashMap { public Iterator iterator() { Collection collection = this.keySet(); Object[] array = collection.toArray(); Arrays.sort(array); return Arrays.asList(array).iterator(); } } class Player implements Comparable{ public String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public int compareTo(Object obj) { Player comparePlayer = (Player)obj; if (this.getName().compareTo(comparePlayer.getName())0) { return 1; } else { return 0; } } } }