1

I have a soccer table that I am trying to sort by games won.

I have a class that implements comparable and looks at the won property. This seems to return the correct value (1, -1 or 0).

class TeamStandings implements Comparable<TeamStandings>{
    protected int matchesPlayed = 0;
    protected int won = 0;
    protected int draw = 0;
    protected int loss = 0;
    protected int goalsScored = 0;
    protected int goalsConceded = 0;
    protected int goalDifference = 0;
    protected int points = 0;

    @Override
    public int compareTo(TeamStandings other){
        // compareTo should return < 0 if this is supposed to be
        // less than other, > 0 if this is supposed to be greater than 
        // other and 0 if they are supposed to be equal

        //System.out.println(this.won + " " + other.won + " " + Integer.valueOf(this.won).compareTo(Integer.valueOf(other.won)));
        return Integer.valueOf(this.won).compareTo(Integer.valueOf(other.won));

    }
}

This sort function should return a sorted hashmap. The hashmap has the teamname as the key and an instance of the teamstandings class as the value.

private static HashMap sortByValues(HashMap map) { 
    List list = new LinkedList(map.entrySet());
    // Defined Custom Comparator here
    Collections.sort(list, new Comparator() {
        public int compare(Object o1, Object o2) {

            System.out.println(((Comparable) ((Map.Entry) (o1)).getValue()).compareTo(((Map.Entry) (o2)).getValue()));
            return ((Comparable) ((Map.Entry) (o1)).getValue())
                    .compareTo(((Map.Entry) (o2)).getValue());          
        }
    });

    // Here I am copying the sorted list in HashMap
    // using LinkedHashMap to preserve the insertion order
    HashMap sortedHashMap = new LinkedHashMap();
    for (Iterator it = list.iterator(); it.hasNext();) {
        Map.Entry entry = (Map.Entry) it.next();
        sortedHashMap.put(entry.getKey(), entry.getValue());
        //System.out.println(entry.getKey());
    } 
    return sortedHashMap;
}

The hashmap sortedtable, takes a string for the team name and a teamstandings class object that contains the games won, lost, etc.

For some reason I can't get the table to sort. It just stays in the unsorted order. I believe it's something to do with the sortbyvalues function at the collection.sort position.

Any ideas how I can use the won value in my class to sort the hashmap?

public void printTable(){

    Map<String, TeamStandings> sortedTable = sortByValues(this.table);

    System.out.println("Group: " + this.groupLetter);
    System.out.println("Team" 
            + "\t" + "MP"
            + "\t" + "W"
            + "\t" + "D"
            + "\t" + "L"
            + "\t" + "GS"
            + "\t" + "GC"
            + "\t" + "GD"
            + "\t" + "P");

    //Iterator<Map.Entry<String, TeamStandings>> iterator = this.table.entrySet().iterator() ;
    Iterator<Map.Entry<String, TeamStandings>> iterator = sortedTable.entrySet().iterator() ;

    while(iterator.hasNext()){
        Map.Entry<String, TeamStandings> team = iterator.next();
        System.out.println(team.getKey() 
                + "\t" + team.getValue().matchesPlayed
                + "\t" + team.getValue().won
                + "\t" + team.getValue().draw
                + "\t" + team.getValue().loss
                + "\t" + team.getValue().goalsScored
                + "\t" + team.getValue().goalsConceded
                + "\t" + team.getValue().goalDifference
                + "\t" + team.getValue().points);
    }
}

Thanks

Dave

Edit:

I think it's something to do with this code, as I printed the list entries and they are not sorted:

    List list = new LinkedList(map.entrySet());
    // Defined Custom Comparator here
    Collections.sort(list, new Comparator() {
        public int compare(Object o1, Object o2) {

            System.out.println(((Comparable) ((Map.Entry) (o1)).getValue()).compareTo(((Map.Entry) (o2)).getValue()));
            return ((Comparable) ((Map.Entry) (o1)).getValue())
                    .compareTo(((Map.Entry) (o2)).getValue());          
        }
    });

I changed my code back to that which I originally posted and it was nothing to do with LinkedList or LinkedHashMap, the code actually worked all along, it was just sorting in ascending order. Which for a soccer league table is obviously not correct.

Edit:

The fix was adding the * -1 shown here:

return Integer.valueOf(this.won).compareTo(Integer.valueOf(other.won)) * -1;

Thanks to @Justin and @falsarella.

falsarella
  • 12,217
  • 9
  • 69
  • 115
Dave Nicholls
  • 13
  • 1
  • 4
  • 1
    You really need use Generics!. Also, see [this](http://stackoverflow.com/questions/12310914/how-to-iterate-through-linkedhashmap-with-lists-as-values) for how to iterate a map with a short version. – Arturo Volpe Aug 28 '14 at 23:24
  • Troubleshooting hint: print `entry.getValue().won` inside the `for (Iterator it = list.iterator(); it.hasNext();) {` iteration, so we can see if the `Collections.sort(list, new Comparator() { ... });` had really sorted, isolating the problem to a specific part of the code. – falsarella Aug 28 '14 at 23:31
  • No, it has not sorted Won: 0 Won: 1 Won: 2 Won: 3 Group: A Team MP W D L GS GC GD P Brazil 3 0 0 3 0 3 -3 0 Italy 3 1 0 2 1 2 -1 3 Germany 3 2 0 1 2 2 0 6 England 3 3 0 0 4 0 4 9 – Dave Nicholls Aug 29 '14 at 04:18
  • That is sorted from smallest to biggest integer – Justin Aug 29 '14 at 05:28
  • @DaveNicholls are you sure you placed the println at the `for (Iterator it = list.iterator(); it.hasNext();) {`, and not inside the `Collections.sort(list, new Comparator() { ... });`? The strings from the print inside the `Collections.sort` obviously won't be sorted: that's why you should verify the prints after the `list` was completely sorted. – falsarella Aug 29 '14 at 11:52
  • Justin and falsarella, thanks sorting in the correct way worked. I can't believe I wasted so much time on this!!!! – Dave Nicholls Aug 29 '14 at 14:33
  • BTW I changed my code back to that which I originally posted and it was nothing to do with LinkedList or LinkedHashMap, the code actually worked all along, it was just sorting in ascending order. Which for a soccer league table is obviously not correct. Thank you Justin and falsarella for spotting the simple mistake! – Dave Nicholls Aug 29 '14 at 14:35

2 Answers2

1

I don't think a HashMap maintains insertion order. Try a TreeMap. or LinkedHashmap as suggested by AVolpe

http://docs.oracle.com/javase/7/docs/api/java/util/TreeMap.html

Justin
  • 1,356
  • 2
  • 9
  • 16
1

Apparently, as @Justin commented, the output is sorted, but in ascendant order:

0, 1, 2, 3

If you want that in descendant order, just change the returned integer sign from the compareTo method:

return Integer.valueOf(this.won).compareTo(Integer.valueOf(other.won)) * -1; 
falsarella
  • 12,217
  • 9
  • 69
  • 115