How to rank the winning ratio in java - java

I've been building a classical Nim game with three java classes. So far, I build almost everything and the last thing I need to do is to rank the player in descending order by winning ratio, which is the score divided by the gamePlayed. What I've tried was to implement the comparables in NimPlayer class. Here is my code:
public class NimPlayer implements Comparable<NimPlayer>{ //initialize comparable
private String userName;
private String familyName;
private String givenName;
static int counter;
private int score;
private int gamePlayed;
private int winRatio = score / (gamePlayed+1); //avoid 0/0, mathmatically wrong
static NimPlayer[] playerList = new NimPlayer[10]; // set an array here
//define NimPlayer data type
public NimPlayer(String userName, String surName, String givenName) {
this.userName = userName;
this.familyName = surName;
this.givenName = givenName;
}
// create new data using NimPlayer data type
public static void createPlayer(String userName, String familyName, String givenName) {
if (counter<10) {
playerList[counter++] = new NimPlayer(userName, familyName, givenName);
} else {
System.out.println("Cannot add more players.");
}
}
public static int getCounter() {
return counter;
}
public static NimPlayer [] getPlayer() {
return playerList;
}
// the getter and the setter of userName, familyName, givenName, score, gamePlayed
#Override
public String toString() {
return winRatio+"% | "+gamePlayed+" games | "+givenName+" "+familyName;
}
#Override
public int compareTo(NimPlayer o) {
return this.winRatio - o.winRatio;
}
}
In the main method, which called Nimsys, I've tried:
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (true) {
System.out.print('$');
String commandin = in.next();
if (commandin.equals("rankings")) {
Arrays.sort(NimPlayer.getPlayer());//sorting with the object type
System.out.println(Arrays.toString(NimPlayer.getPlayer()));
}
}
However, when I have two players in play and their score and gamePlayedare not null, the execution still goes to NullPointerException. Any help is highly appreciated.

The error you are getting is because you are initializating the array with a size of 10. The sort operation will traverse all 10 positions, and some of them will be null. If you create 10 players, then it should work without any problem.
To have a dynamic size, use an ArrayList instead, updating the following:
static List<NimPlayer> playerList = new ArrayList<>();
public static void createPlayer(String userName, String familyName, String givenName) {
if (counter < 10) {
playerList.add(new NimPlayer(userName, familyName, givenName));
counter++;
} else {
System.out.println("Cannot add more players.");
}
}
For sorting the List:
Collections.sort(NimPlayer.playerList);
Besides this, I think you have some flaws in your code.
First, you are initializing the winRatio in the field declaration and, at least from what I can see in your code, is not getting updated never, so it will be always 0. A way to overcome this is to use the getters and setters to trigger the calculation each time you ask for the value.
public Float getWinRatio() {
return Float.valueOf(getScore()) / (getGamePlayed() + 1);
}
Second, you set the winRatio as an int. This will ignore all the decimals in the divisions, so the results won't be accurate.
Also, you seem to be combining the data of players with the logic of the game. You should split the NimPlayer class from the logic containing all the players in the game.

Related

How to sort a continuously updated (dynamic) object in an array

I am building a classical Nim game. So far, I've done the player part and the game part. Now, I am trying to sort(rank) the object in an array. I've built the following for sorting:
playerList
winRatio, which is set in the NimPlayer class with its getter.
The aim :
to sort the winRatio descendingly, which means from the highest score to the lowest one. The ratio is calculated by score/gamePlayed.
If there's a tie, sort using userName alphabetically.
I've referred to this issue: How to sort an array of objects in Java?
I know what I should do is use the Comparable or Comparator for sorting but from the article, they sort using the attributes in the object (All the information I've found so far). What I am dealing with is the continuously updated data outside the constructor.
What I've tried was directly printed out the data without sorting.
Here is my related code (NimPlayer):
public class NimPlayer {
private String userName;
private String familyName;
private String givenName;
static int counter;
private int score;
private int gamePlayed;
static NimPlayer[] playerList = new NimPlayer[2]; // set an array here
//define NimPlayer data type
public NimPlayer(String userName, String surName, String givenName) {
this.userName = userName;
this.familyName = surName;
this.givenName = givenName;
}
// create new data using NimPlayer data type
public static void createPlayer(String userName, String familyName, String givenName) {
if (counter<10) {
playerList[counter++] = new NimPlayer(userName, familyName, givenName);
} else {
System.out.println("Cannot add more players.");
}
// all the getter and setter related to the constructor; the getter of the player list.
}
public void setScore(int score) {
this.score=score;
}
public int getScore() {
return score;
}
public void setGamePlayed (int gamePlayed) {
this.gamePlayed = gamePlayed;
}
public int getGamePlayed() {
return gamePlayed;
}
public int getWinRatio () {
return Math.round(Float.valueOf(getScore())/ (getGamePlayed()+1)*100) ;
}
}
This is my main class (Nimsys)
public static void searchAndPrintRankingData() {
for (int i = 0; i < NimPlayer.getCounter(); i++) {
String familyName = NimPlayer.getPlayer()[i].getFamilyName();
String givenName = NimPlayer.getPlayer()[i].getGivenName();
int score = NimPlayer.getPlayer()[i].getScore();
int gamePlayed = NimPlayer.getPlayer()[i].getGamePlayed();
double winRatio = score/(gamePlayed+1);//wrong calculation for testing
System.out.println(winRatio+"% | "+gamePlayed+" games | "+givenName+" "+familyName);
}
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (true) {
System.out.print('$');
String commandin = in.next();
if (commandin.equals("rankings")) {
String commandOrder = in.nextLine().trim();
if (commandOrder.equals("asc")) {
//sort the data
searchAndPrintRankingData();
}
if (commandOrder.equals("") || commandOrder.equals("desc")) {
//sort the data
searchAndPrintRankingData();
}
}
}
Any help is highly appreciated.
Use Interface Comparator
Do it as follows:
import java.util.Arrays;
import java.util.Comparator;
class NimPlayer {
private String userName;
private String familyName;
private String givenName;
private static int counter;
private static final int SIZE = 4;
private int score;
private int gamePlayed;
static NimPlayer[] playerList = new NimPlayer[SIZE];
public NimPlayer(String userName, String surName, String givenName) {
this.userName = userName;
this.familyName = surName;
this.givenName = givenName;
}
public static void createPlayer(String userName, String familyName, String givenName) {
if (counter < SIZE) {
playerList[counter++] = new NimPlayer(userName, familyName, givenName);
} else {
System.out.println("Cannot add more players.");
}
}
public static int getCounter() {
return counter;
}
public static NimPlayer[] getPlayerList() {
return playerList;
}
public String getUserName() {
return userName;
}
public String getFamilyName() {
return familyName;
}
public String getGivenName() {
return givenName;
}
public void setScore(int score) {
this.score = score;
}
public int getScore() {
return score;
}
public void setGamePlayed(int gamePlayed) {
this.gamePlayed = gamePlayed;
}
public int getGamePlayed() {
return gamePlayed;
}
public int getWinRatio() {
return Math.round((Float.valueOf(score) / gamePlayed) * 100);
}
#Override
public String toString() {
return "User Name: " + userName + ", Name: " + givenName + " " + familyName + ", Score: " + score
+ ", Games Played: " + gamePlayed + ", Win ratio: " + getWinRatio();
}
}
public class Main {
static void searchAndPrintRankingData() {
NimPlayer[] players = NimPlayer.getPlayerList();
Arrays.sort(players,
Comparator.comparing((NimPlayer::getWinRatio)).reversed().thenComparing(NimPlayer::getUserName));
Arrays.stream(players).forEach(System.out::println);
}
public static void main(String[] args) {
NimPlayer.createPlayer("Avi", "Avinash", "Arvind");
NimPlayer.createPlayer("Harry", "Potter", "Harry");
NimPlayer.createPlayer("Vishy", "Anand", "Vishwanathan");
NimPlayer.createPlayer("Bond", "Bond", "James");
NimPlayer[] players = NimPlayer.getPlayerList();
players[0].setGamePlayed(2);
players[0].setScore(40);
players[1].setGamePlayed(3);
players[1].setScore(75);
players[2].setGamePlayed(2);
players[2].setScore(120);
players[3].setGamePlayed(4);
players[3].setScore(100);
System.out.println("Unsorted: ");
Arrays.stream(NimPlayer.getPlayerList()).forEach(System.out::println);
System.out.println();
System.out.println("Sorted on win ratio (then name, in case of tie): ");
searchAndPrintRankingData();
}
}
Output:
Unsorted:
User Name: Avi, Name: Arvind Avinash, Score: 40, Games Played: 2, Win ratio: 2000
User Name: Harry, Name: Harry Potter, Score: 75, Games Played: 3, Win ratio: 2500
User Name: Vishy, Name: Vishwanathan Anand, Score: 120, Games Played: 2, Win ratio: 6000
User Name: Bond, Name: James Bond, Score: 100, Games Played: 4, Win ratio: 2500
Sorted on win ratio (then name, in case of tie):
User Name: Vishy, Name: Vishwanathan Anand, Score: 120, Games Played: 2, Win ratio: 6000
User Name: Bond, Name: James Bond, Score: 100, Games Played: 4, Win ratio: 2500
User Name: Harry, Name: Harry Potter, Score: 75, Games Played: 3, Win ratio: 2500
User Name: Avi, Name: Arvind Avinash, Score: 40, Games Played: 2, Win ratio: 2000
Note: In case you wish to use ArrayList<NimPlayer> in searchAndPrintRankingData, given below is the code for the same:
static void searchAndPrintRankingData() {
List<NimPlayer> players = new ArrayList<NimPlayer>(Arrays.asList(NimPlayer.getPlayerList()));
Collections.sort(players,
Comparator.comparing((NimPlayer::getWinRatio)).reversed().thenComparing(NimPlayer::getUserName));
players.stream().forEach(System.out::println);
}
For sort ascending use the code link you mentioned. As long as the players have been added to the array, you can sort them. The code below is the key (you will need to adapt variable names etc)
You will need to add winRation etc to NimPlayer constructor and as element of the array, then it can sort it.
#Test
public void sortBooks() {
Book[] books = {
new Book("foo", "1", "author1", "pub1"),
new Book("bar", "2", "author2", "pub2")
};
// 1. sort using Comparable
Arrays.sort(books);
System.out.println(Arrays.asList(books));
// 2. sort using comparator: sort by id
Arrays.sort(books, new Comparator<Book>() {
#Override
public int compare(Book o1, Book o2) {
return o1.id.compareTo(o2.id);
}
});
System.out.println(Arrays.asList(books));
}
Change this :
return o1.id.compareTo(o2.id);
To:
return o1.winRatio.compareTo(o2.winRatio);
It should work by implementing the Comparable interface, as the compareTo method will be called each time you want to sort and will have the updated data.
To sort first by winRatio, and if equal, by name, it can work with the following code:
public class NimPlayer implements Comparable<NimPlayer> {
...
#Override
public int compareTo(NimPlayer o) {
// get the comparison of the win ratios
int ratioCompare = this.getWinRatio().compareTo(o.getWinRatio());
// if the winRatio is equal, return the reverse comparison of the usernames
return (ratioCompare != 0) ? ratioCompare : o.userName.compareTo(this.userName);
}
}
Then, to sort the array, you just need to use the Arrays class:
Arrays.sort(NimPlayer.playerList);
Arrays.sort(NimPlayer.playerList, Collections.reverseOrder()); // for desc order
The problem you may face with that is if you always want to have the username ordered ASC.
In that case, your only option is to implement two different comparators, one for ascending and another for descending orders:
Comparator<NimPlayer> ascComparator = (p1, p2) -> {
int ratioCompare = p1.getWinRatio().compareTo(p2.getWinRatio());
return (ratioCompare != 0) ? ratioCompare : p1.getUserName().compareTo(p2.getUserName());
};
Comparator<NimPlayer> descComparator = (p1, p2) -> {
int ratioCompare = p2.getWinRatio().compareTo(p1.getWinRatio());
return (ratioCompare != 0) ? ratioCompare : p1.getUserName().compareTo(p2.getUserName());
};
To sort using those comparators, just pass the comparators into the Arrays.sort method:
Arrays.sort(NimPlayer.playerList, ascComparator);
Arrays.sort(NimPlayer.playerList, descComparator);
Your NimPlayer needs to implement Comparable interface:
public class NimPlayer implements Comparable<NimPlayer> {
#Override
public int compareTo(NimPlayer other) {
if (other.getWinRatio() == this.getWinRatio()) {
return this.getUserName().compareTo(other.getUserName());
} else if (other.getWinRatio() > this.getWinRatio()) {
return 1;
}
return -1;
}
public static NimPlayer[] getPlayer() {
Arrays.sort(playerList);
return playerList;
}
}
Also, you need to fix the size of your playerList, which is set to 2 static NimPlayer[] playerList = new NimPlayer[2];, and then you try to add up to 10 players :)
And when adding players to the list you'd better compared counter to actual playerList.length;

How to check the duplicate object in the array

I am a java beginner and I am designing a Nim game for many players to join. I've done some research but I don't know if my implementation is correct. The aim is to check the duplicate object in an array. I've already checked some articles, and I'll reference them in the last part of this article.
For the NimPlayer class. I've created some things.
I've defined the NimPlayer object type.
Using the type, I can initialize the player in the limited space.
I initialize an array for saving player's data by following the steps here: Storing object into an array - Java
public class NimPlayer {
String userName;
String familyName;
String givenName;
NimPlayer [] playerList = new NimPlayer[10]; //set an array here
int id;
//define NimPlayer data type
public NimPlayer(String userName,String surName, String givenName) {
this.userName = userName;
this.familyName = surName;
this.givenName = givenName;
}
//create new data using NimPlayer data type
public void createPlayer(String userName, String familyName, String givenName) {
playerList[id++] = new NimPlayer(userName, familyName, givenName);
}
In the main method, I have created some features for players to use:
addplayer - let the user can add players in the game to compete.
To add the player, the Syntax like this:
$addplayer userName,familyName,givenName
to validate the input, I split the input and store them in the new object.
public static String[] splitName(String inputName) {
String [] splittedLine = inputName.split(",");
String userName = splittedLine[0].trim();
String familyName = splittedLine[1].trim();
String givenName = splittedLine[2].trim();
String [] name = new String[3];
name[0] = userName;
name[1] = familyName;
name[2] = givenName;
return name;
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
//create new object to save data
NimPlayer playerData = new NimPlayer(null, null, null);
System.out.print('$');
String commandInput = in.next();
while (true) {
if (commandInput.equals("addplayer")) {
String inputName = in.nextLine();
String[] name = splitName(inputName);
String userName = name[0];
String familyName = name [1];
String givenName = name[2];
playerData.createPlayer(userName, familyName, givenName);
for (int i = 0; i < playerData.playerList.length; i++) {
NimPlayer player = playerData.playerList[i];
System.out.println(player.getUserName()); }
}
So far, I have two questions here.
Every time I enter a set of data, it seems my "playerData" provokes the NullPointerException when looping through the object, but since my name input is multiple, I have to create a new object in the main method for saving input.
For checking if there is the duplicate "userName" in the set of the "inputName", I loop through the objects in an array. How can I access the "userName" in this situation?
for checking duplicate, I've checked:
Java - Loop through instances of a class rather than calling a method for each separate instance
What is a NullPointerException, and how do I fix it?
Java Array, Finding Duplicates
You should address then following things in your design/code:
Since you are creating a player using createPlayer(String userName, String familyName, String givenName), you should make the constructor, NimPlayer(String userName,String surName, String givenName) private so that it can not be called from outside of the class, NimPlayer. Also, declare createPlayer as static so that it doesn't need a NimPlayer object to be called on.
You need to have a static counter to keep track of the number of players and check the value of this counter before adding a new player to playerList.
You should also check the size of the resulting array after inputName.split(","). Similarly, you should check the size of the returned array from splitName before you access any element from it.
Given below is the code incorporating the points mentioned above:
import java.util.Scanner;
class NimPlayer {
private String userName;
private String familyName;
private String givenName;
//...
// public getters and setters of userName, familyName, and givenName
//...
private static int counter = 0;
private static NimPlayer[] playerList = new NimPlayer[10];
private NimPlayer(String userName, String familyName, String givenName) {
this.userName = userName;
this.familyName = familyName;
this.givenName = givenName;
}
public static void createPlayer(String userName, String familyName, String givenName) {
if (counter < 10) {
playerList[counter++] = new NimPlayer(userName, familyName, givenName);
} else {
System.out.println("The list is full.");
}
}
public static int getCounter() {
return counter;
}
public static NimPlayer[] getPlayers() {
return playerList;
}
}
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (true) {
System.out.print('$');
String commandInput = in.next();
if (commandInput.equals("addplayer")) {
String inputName = in.nextLine();
String[] name = splitName(inputName);
if (name != null && name.length == 3) {
NimPlayer.createPlayer(name[0], name[1], name[2]);
}
} else {
break;
}
}
for (int i = 0; i < NimPlayer.getCounter(); i++) {
System.out.println(NimPlayer.getPlayers()[i].getUserName());
}
}
public static String[] splitName(String inputName) {
String[] splittedLine = inputName.split(",");
String[] name = null;
if (splittedLine.length == 3) {
String userName = splittedLine[0].trim();
String familyName = splittedLine[1].trim();
String givenName = splittedLine[2].trim();
name = new String[3];
name[0] = userName;
name[1] = familyName;
name[2] = givenName;
}
return name;
}
}
I didn't understand your another question:
For checking if there is the duplicate "userName" in the set of the
"inputName", I loop through the objects in an array. How can I access
the "userName" in this situation?

If I create an array of the parental class, how do I access a method from the sub class through the array object?

I have a program I am working with to help me practice my coding skills. The program has the following scenario: there is a classroom of 20 students, where the record is taken of the students' names, surnames, and age. Half of these students take part in the school's athletics. Here, record is kept of their races that they have done and the ones they've won.
In this program, I have three classes:
runStudents - class with main method
Students (String name, String surname, int age) - parental class
AthleticStudents (String name, String surname, int age, int races, int victories) - sub class
The user should be able to add another race (and win) to the object. As seen by the code provided, an Array is created to store the 20 Students objects. I have to be able to access a method to alter the object in the array, but this method is not in the parental class (the class the objects are created from.
public class Students
{
private String name;
private String surname;
private int age;
public Students()
{
}
public Students(String name, String surname, int age)
{
this.name = name;
this.surname = surname;
this.age = age;
}
public String getName()
{
return this.name;
}
public String getSurname()
{
return this.surname;
}
public double getAge()
{
return this.age;
}
public void setName(String name)
{
this.name = name;
}
public void setSurname(String surname)
{
this.surname = surname;
}
public void setAge(int age)
{
this.age = age;
}
public String toString()
{
return String.format("name\t\t: %s\nsurname\t\t: %s\nage\t\t: %s",
this.name, this.surname, this.age);
}
}
public class AthleticStudents extends Students
{
private int races;
private int victories;
public AthleticStudents()
{
}
public AthleticStudents(String name, String surname, int age, int
races, int victories)
{
super(name, surname, age);
this.races = races;
this.victories = victories;
}
public int getRaces()
{
return this.races;
}
public int getVictories()
{
return this.victories;
}
public void setRaces(int races)
{
this.races = races;
}
public void setVictories(int victories)
{
this.victories = victories;
}
public void anotherRace()
{
this.races = this.races + 1;
}
public void anotherWin()
{
this.victories = this.victories + 1;
}
public String toString()
{
return super.toString() + String.format("\nnumber of races\t:
%s\nnumber of wins\t: %s", this.races, this.victories);
}
}
public class runStudents
{
public static void main(String[]args)
{
Students[] myStudents = new Students[20];
myStudents[0] = new Students("John", "Richards", 15);
myStudents[1] = new AthleticStudents("Eva", "Grey", 14, 3, 1);
myStudents[2] = new Students("Lena", "Brie", 15);
for (int i = 0; i < 3; i++)
System.out.println(myStudents[i].toString() + "\n\n");
}
}
I want to be able to do the following:
AthleticStudents[1].anotherRace();
but cannot do so as the array object is derived from the parental class, and I declared the method in the sub class. How can I link the two?
I assume that you create an array of the parent class instances. Just cast the instance this way (you better check whether the element is the instance of a subclass):
if (AthleticStudents[1] instanceof AthleticStudents)
((AthleticStudents) AthleticStudents[1]).anotherRace();
I'm not sure if this is exactly what you're looking for but it worked well for me. Instead of trying to access AthleticStudents method anotherRace() like that, try this in your main method.
Students[] myStudents = new Students[20];
myStudents[0] = new Students("John", "Richards", 15);
myStudents[1] = new AthleticStudents("Eva", "Grey", 14, 3, 1);
myStudents[2] = new Students("Lena", "Brie", 15);
AthleticStudents addRace= (AthleticStudents)myStudents[1];
addRace.anotherRace(); //This will increment Eva's race count to 4
for (int i = 0; i < 3; i++)
System.out.println(myStudents[i].toString() + "\n\n");
All I did was cast the element into an object AthleticStudents named 'addRace'. By casting myStudents[1] to this new object you are able to access all of AthleticStudents methods.
I just saw the other answer posted which works just as well!
Hope this helps!
I’m not sure that i understand your question, because you are a bit inconsistent with your capitalization. runStudents is a class, while AthleticStudents is both a class and an array. But i’ll try.
IF i did understand your question, you have an array Student[] studentArray. Some Student objects in studentArray are AthleticStudents, others are not. You have a specific AthleticStudent eva which is in studentArray[] having let’s say index 1, and you want to add to her anotherRace(). Your call studentArray[1].anotherRace does not compile because the compiler treats that element as a Student and not as a AthleticStudent.
The trick is to cast the element to AthleticStudent. I omit the test of the element of being really an AthleticStudent; you will have to do that test in your code.
((AthleticStudent) studentArray[1]).anotherRace();

Set and get loop of data by putting into list in java

i have for loop where i get data to send to other method in different class
UserManagerImpl.java
for (User user: userList) {
surveyModel survey = new SurveyModel();
survey.setSurveyData(Id, comment, serveyScore, grade);
}
In other class i have set and get to create list of datas and then want to fetch it by get method.
surveyModel.java
public class SurveySentimentModel {
public static String delimiter = "|||";
private List scores = new ArrayList();
private List negativeData = new ArrayList();
private List PositiveData = new ArrayList();
public void setSurveyData(String Id, String comment, double Score, String grade) {
//want to add score to scores list
//if grade positive add to positive list or else negative after delimiting
}
public double getTotalScore() {
//calculate the sum of scores
return totalScore;
}
public String getTotalSentimentgrade() {
if (totalScore> 0) {
return "Positive";
}
return "Negative";
}
public List getSurveyData() {
//Want to merge list - first negative and then positive
return new ArrayList();
}
}
SurveyModel.java
private String grade;
private Number Score;
private String Id;
private String comment;
public SurveyModel(String Id, String comment, double Score, String grade) {
this.grade= grade;
this.Score= Score;
this.comment = comment;
this.Id = Id;
}
public SurveyModel() {
// TODO Auto-generated constructor stub
}
// getters and setters
IN here i want to
1.) Add score to scores list
2.) want to add graddes to list by negative first with delimiter then positive.
3.) want to get total score.
How could i achive my requirement. I am new to java please help me on this.
Here's a suggestion:
This is the Model class:
public class SurveySentimentModel {
public static String delimiter = "|||";
private List<SurveyModel> scores = new ArrayList();
private List<SurveyModel> negativeData = new ArrayList();
private List<SurveyModel> positiveData = new ArrayList();
public void setSurveyData(String Id, String comment, double score, String grade) {
SurveyModel survey = new SurveyModel(id, comment, score, grade );
scores.add(survey)
if(score >= 0){
positiveData.add(survey);
}else{
negativeData.add(survey);
}
}
public double getTotalScore() {
double sum = 0;
for(SurveyModel s: scores){
sum += s.getScore();
}
return sum;
}
public List getSurveyData() {
List<SurveyModel> joined = new ArrayList(negativeData);
joined.addAll(positiveData)
return joined;
}
}
This is the loop:
SurveySentimentModel sentiments = new SurveySentimentModel();
for (User user: userList) {
sentiments.setSurveyData(user.getId(), user.getComment(), user.getSurveryScore(), user.getGrade());
}

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!
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!
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(){...}
}
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;
}
}

Categories