user971889
user971889

Reputation: 215

Android Collections.compare() change criteria

I am developing a game for android and I save the scores in a text file of the form "100&playername1,93&playername1,1950&playername2" etc. i.e. it is totally unordered.

Now I am trying to make a high score interface and I am aware that to sort the scores I should use String.split(",") followed by String.split("&")[0] to get the scores and put these in an ArrayList and then call Collections.compare(list). However once I have done that I then have no way of finding the names associated with the score.

Could anyone help me with this please. I have tried sorting the whole string in between brackets (putting the phrase "100&playername1" into the array, but that can't sort according to orders of magnitude. By this I mean it would put 100 ahead of 1950.

Thanks for any help!

Upvotes: 2

Views: 983

Answers (3)

eboix
eboix

Reputation: 5133

Make a class called UsernameScorePair. Once you have split the scores and the usernames, put them in pairs (one for each "score&username").

For example, this class definition could work:

public class UsernameScorePair {

    private String name;
    private int score;

    public UsernameScorePair(String name, int score) {
        this.name = name;
        this.score = score;
    }

    public String getName() {
        return name;
    }

    public int getScore() {
        return score;
    }

}

Make a class called UsernameScorePairComparator that implements Comparator.

In the compare(Object o1, Object o2) method, cast the Objects to UsernameScorePairs and compare the scores. For example:

public class UsernameScorePairComparator {

    public UsernameScorePairComparator() {
    }

    public int compare(Object o1, Object o2) {
        UsernameScorePair usp1 = (UsernameScorePair)o1;
        UsernameScorePair usp2 = (UsernameScorePair)o2;

        return usp1.getScore() - usp2.getScore();
    }
}

Then use Collections.sort like this:

Collections.sort(listofpairs, new UsernameScorePairComparator())

I don't remember if it sorts in ascending order or descending order. If it's ascending order, then just change return usp1.getScore() - usp2.getScore(); to return usp2.getScore() - usp1.getScore();

EDIT

A Comparator basically compares two objects. In its compareTo method, it returns a negative value if the first is less than the second, a positive one if the first is greater than the second, and zero if they are both equal.

You can implement a Comparator (as I just did) to suit your needs. Then, using that Comparator, you can use standard API methods such as Collections.sort().

I hope this works!

Upvotes: 5

Guillaume
Guillaume

Reputation: 22822

A way is to have a custom object (call it Score) that contains the score and the player. Then put your scores in a list of Score, with a custom comparator that compares on scores.

final String wholeString = "100&playername1,93&playername1,1950&playername2";

final List<Score> scoresForPlayers = new ArrayList<Score>();
final String[] scores = wholeString.split(",");
for (String score : scores) {
    final String[] split = score.split("&");
    scoresForPlayers.add(new Score(Integer.parseInt(split[0]), split[1]));
}
Collections.sort(scoresForPlayers, new Comparator<Score>() {
    @Override
    public int compare(Score o1, Score o2) {
        return o1.score.compareTo(o2.score);
    }
});

class Score {
    private final Integer score;
    private final String player;

    public Score(Integer score, String player) {
        this.score = score;
        this.player = player;
    }
}

Upvotes: 0

asenovm
asenovm

Reputation: 6517

You can iterate through the elements and create a new Player for each String like so:

public class Player implements Comparable<Player>{

private int mScore;

private final String mName;

public Player(final int score, final String name) {
    mScore = score;
    mName = name;
}

public void setScore(final int score) {
    mScore = score;
}

@Override
public int compareTo(Player other) {
    return mScore - other.mScore;
}

}

Now you just need to call Collections.sort(List<Player>); And you can even make the Player class implement the Serializable interface:

import java.io.Serializable;

public class Player implements Comparable<Player>, Serializable {

private static final long serialVersionUID = 8257815475849584162L;

private int mScore;

private final String mName;

public Player(final int score, final String name) {
    mScore = score;
    mName = name;
}

public void setScore(final int score) {
    mScore = score;
}

@Override
public int compareTo(Player other) {
    return mScore - other.mScore;
}

    readObject(){...}
    writeObject(){...}

 }

Upvotes: 0

Related Questions