-1

I have three integer values along with its text. My requirement is to give rank to all of them.

E.g. I have A = 50 points, B = 500 Points, C = 50 points.

Now I would like to compare all of these and find max and equal values and its according name(like, A/B/C).

EDIT :: As a output it should return, B = 1st Rank, A = 2nd Rank, C = 2nd Rank.

If anyone has any idea about how can I implement code as per my requirement then, it would be great.

Thanks in advance.

public class ScoreVO implements Comparator<Integer> {

    private String playerName = Constants.BLANK_STRING;
    private int playerScore;

    public String getPlayerName () {
        return playerName;
    }

    public void setPlayerName ( String playerName ) {
        this.playerName = playerName;
    }

    public int getPlayerScore () {
        return playerScore;
    }

    public void setPlayerScore ( int playerScore ) {
        this.playerScore = playerScore;
    }

    @Override
    public int compare ( Integer o1, Integer o2 ) {
        return o2.compareTo ( o1 );
    }
}

Here is my class with Comparator<>.

Please suggest me if I am wrong.

anddev
  • 3,144
  • 12
  • 39
  • 70
  • 1
    Well, what have you tried so far? Have you considered creating a class representing the name/score pair, and then implementing `Comparable` and sorting? – Jon Skeet May 21 '15 at 06:16
  • @Jon Skeet, yes I created Class with name & score and also implement Comparator. But after that how can I compare all these value and find greater / equal values. – anddev May 21 '15 at 06:18
  • 1
    Why would you implement `Comparator`? You'd implement `Comparable` or whatever the class name is. Please show us what you've tried - how far you've got. – Jon Skeet May 21 '15 at 06:21
  • @anddev post your class and we can assist. – Kenneth Clark May 21 '15 at 06:22
  • Please find my edited code. – anddev May 21 '15 at 06:26

4 Answers4

1

A sample running code which gives output shown below as per your requirement along with player rank. There is a separate method assignRank(List<>) which you can use to assign ranks to players.

Score List: [ScoreVO [playerName=B, playerScore=500, playerRank=1], ScoreVO [playerName=A, playerScore=50, playerRank=2], ScoreVO [playerName=C, playerScore=50, playerRank=2]]

public class ScoreExample {

    public static void main(String[] args) {
        List<ScoreVO> scoreList = new ArrayList<ScoreVO>();
        scoreList.add(new ScoreVO("A", 50));
        scoreList.add(new ScoreVO("C", 50));
        scoreList.add(new ScoreVO("B", 500));
        Collections.sort(scoreList);
        assignRank(scoreList);
        System.out.println("Score List: "+scoreList);
    }

    private static void assignRank(List<ScoreVO> scoreList) {
        int rank = 0;
        int score = 0;
        for(ScoreVO scoreVO : scoreList) {
            if(score != scoreVO.getPlayerScore()) {
                rank++;
                scoreVO.setPlayerRank(rank);
                score = scoreVO.getPlayerScore();
            } else {
                scoreVO.setPlayerRank(rank);
            }
        }
    }
}
class ScoreVO implements Comparable<ScoreVO> {
    public String playerName;
    public int playerScore;
    public int playerRank;

    public ScoreVO(String playerName, int playerScore) {
        this.playerName = playerName;
        this.playerScore = playerScore;
    }

    public String getPlayerName() {
        return playerName;
    }

    public void setPlayerName(String playerName) {
        this.playerName = playerName;
    }

    public int getPlayerScore() {
        return playerScore;
    }

    public void setPlayerScore(int playerScore) {
        this.playerScore = playerScore;
    }

    public int getPlayerRank() {
        return playerRank;
    }

    public void setPlayerRank(int playerRank) {
        this.playerRank = playerRank;
    }

    @Override
    public int compareTo(ScoreVO o) {
        if(o.getPlayerScore() != getPlayerScore()) {
            if(getPlayerScore() > o.getPlayerScore())
                return -1;
            else
                return 1;
        } 
        return getPlayerName().compareTo(o.getPlayerName());
    }

    @Override
    public String toString() {
        return "ScoreVO [playerName=" + playerName + ", playerScore="
                + playerScore + ", playerRank=" + playerRank + "]";
    }
}
Kulin Soni
  • 74
  • 1
  • 5
0

ScoreVO should implement Comparable<ScoreVO>. And your compareTo method looks like this:

@Override
public int compareTo ( ScoreVO o ) {
    if(playerScore != o.playerScore)
       return Integer.compare(playerScore, o.playerScore);
    return playerName.compareTo(o.playerName);
}
Pham Trung
  • 11,204
  • 2
  • 24
  • 43
  • This is incorrect. Comparable.compareTo receives one argument ans is intended to compare it against this. – Sharon Ben Asher May 21 '15 at 06:37
  • @sharonbn you are right, thanks, I just edited it :) – Pham Trung May 21 '15 at 06:39
  • @Pham Trung, this will return me sorting data thats true. But after that what should I do to comapare those three values? That what I want to know? Should I compare those via if/else? – anddev May 21 '15 at 06:42
  • @anddev You can call [Collections.sort()](https://docs.oracle.com/javase/6/docs/api/java/util/Collections.html#sort%28java.util.List%29) or [Arrays.sort()](https://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html#sort%28java.lang.Object[]%29), and they will give you correct order – Pham Trung May 21 '15 at 06:44
  • the method will throw NPE if o is null. it is also better practice to use getter, since it may have some logic (perhaps in the future...) – Sharon Ben Asher May 21 '15 at 06:51
  • @sharonbn how an object can be compared with a `null`? throwing exception should be correct behaviour. – Pham Trung May 21 '15 at 06:57
  • an array may have null values. if you sort it, you will get cmpareTo with null arg – Sharon Ben Asher May 21 '15 at 07:01
  • @sharonbn, it is not the problem, you just bring in different context, the point is, you can not compare anything with `null`. And when you do, it is a mistake and an exception should be thrown, this is the main concept. – Pham Trung May 21 '15 at 07:26
  • that is not true. Application logic may include cases of null Objects. in any case, you need to protect your code from NPE, even if its only to protect from bugs or user error etc – Sharon Ben Asher May 21 '15 at 07:28
  • @sharonbn `null` is not even considered as object, please point me to an article or example of real life issue that you need to do that, or else, your point is invalid. – Pham Trung May 21 '15 at 07:31
  • @sharonbn please take a look at [this](http://stackoverflow.com/questions/7168497/undocumented-string-comparetonull-npe) :) – Pham Trung May 21 '15 at 07:38
  • Database column (or any other external input) may contain null values. also, BUGS may cause an array to contain null values. now, consider the case where you have a web site that is running a Java app that is fetching some data from an RDBMS and because of a bug (i.e. missing constraint?) you end up with null values in an array you're sorting. do you know what happens in a web server when the Java application throws NPE? it will return HTTP code 500. do you what happens on the client side in this case? do you think this is the correct behavior of a website??? – Sharon Ben Asher May 21 '15 at 07:40
  • @sharonbn you are talking about totally different point, how to handle NPE is different issue, and how to handle null content is different issue, we only discuss about whether we should allow `null` as a valid parameter of compareTo method, and the answer is no. the reason is simple if `Object a compareTo (null) < 0 `, so `null compareTo(a) > 0`, but you cannot do that, and NPE will be thrown anyway, I hope this made my point clear :) – Pham Trung May 21 '15 at 07:43
  • and I maintain that this is a design-level considearion, null as meaning "empty value" is common practice. – Sharon Ben Asher May 21 '15 at 07:46
  • @Pham Trung - do you surround your servlets with catch of NPE? that is highly uncommon practice, not to mention undesirable during testing – Sharon Ben Asher May 21 '15 at 07:48
  • @sharonbn please take this simple, first, throwing exception is part of the contract of `compareTo` interface, second, even if you have a null-safe `compareTo` method, you cannot stop `Collections.sort` or similar call `null.compareTo`, and at that point, NPE will be thrown anyway, and you have to handle NPE at higher level, no matter what you do. – Pham Trung May 21 '15 at 07:51
  • now you digressing. like I said, null == "empty" is common practice. for example, in RDBMSs – Sharon Ben Asher May 21 '15 at 07:53
  • @sharonbn this arguing is not effective, My main point is all about `compareTo`, that's all, if you feel angry or smth, you can stop and continue this later, I will be there, not rush my friend :) – Pham Trung May 21 '15 at 07:55
0

You should implment Comparable for ordering purpuses, and equals() for equation (that can use compareTo)

like this

public class ScoreVO implements Comparable<ScoreVO> {

    @Override
    public int compareTo(ScoreVO other) {
        return other == null ? 1 : getPlayerScore() - other.getPlayerScore();
    }

    @Override
    public boolean equals(object other) {
        return !(other instanceof ScoreVO) ? false : compareTo(other) == 0 ;
    }
}

However, you probably want to compare equality based on player name. think of putting ScoreVO object in a map - what is the key? so -

    @Override
    public boolean equals(object other) {
        return other == null  ||  !(other instanceof ScoreVO) ? false :             
               getPlayerName.equals(other.getPlayerName()) ;
    }
Sharon Ben Asher
  • 13,849
  • 5
  • 33
  • 47
0

As there are just three values, it is possible to hard-code all operations. You can think of a very compact and efficient way to work this out.

Every comparison of two values can give an outcome >, = or <. Assigning the value 0, 1 or 2 to these, you can pack the three comparisons in a single number using base 3 encoding. You will end up with a number in range 0 to 26, and every different value corresponds to a different answer that you can tabulate (or process in a switch statement).

int Compare(int A, int B) { return A > B ? 0 : (A == B ? 1 : 2); }

char* Answer[27]= { "A1B2C3", "A1B1C3", "B1A2C3", ... }; // To be filled
return Answer[Compare(A, B) + 3 * compare(B, C) + 9 * compare(A, C)];