0

I have an application with a quizz and an activity where I want there to be the top 5 score with the players who made those scores. I have 2 ArrayLists, that stores the scores for one and the other stores the names of the players. I managed to make the list with the scores but i don't know how to have the right names next to the peer scores.

An image of what I have : https://i.stack.imgur.com/7PxmR.png

And an image of what I am looking for : https://i.stack.imgur.com/HNEsU.png

I have tried with a Map but i didn't know that 2 same keys can not be stored so that's impossible, but there may be a way to have some kind of arraylist with indexes but that can have 2 different informations, I don't know.

My 2 ArrayLists :

public static ArrayList<Integer> scoresList = new ArrayList<>();

public static ArrayList<String> namesList = new ArrayList<>();

My way to to have the 5 bests scores :

public class HistoryActivity extends AppCompatActivity {

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_history);

        TextView first = (TextView) findViewById(R.id.history_activity_first);
        TextView second = (TextView) findViewById(R.id.history_activity_second);
        TextView third = (TextView) findViewById(R.id.history_activity_third);
        TextView fourth = (TextView) findViewById(R.id.history_activity_fourth);
        TextView fifth = (TextView) findViewById(R.id.history_activity_fifth);

        Collections.sort(scoresList, Collections.reverseOrder());

        first.setText("Best score is : " + scoresList.get(0));

        if (scoresList.size() >= 2) {
            second.setText("2nd best score is : " + scoresList.get(1));
        }

        if (scoresList.size() >= 3) {
            third.setText("3rd best score is : " + scoresList.get(2));
        }

        if (scoresList.size() >= 4) {
            fourth.setText("4th best score is : " + scoresList.get(3));
        }

        if (scoresList.size() >= 5) {
            fifth.setText("5th best score is : " + scoresList.get(4));
        }
    }
}

Thanks

  • Isn't as simple as write something like this: `first.setText("Best score is : " + scoresList.get(0) + "-" + namesList .get(0));` ? You can make this work using ListView (or RecyclerView) and adapters as well – Shermano Oct 02 '19 at 17:46
  • But nameList.get(0) does not match with scoreList.get(0) because there is a sort which allows me to access the greatest values of scoreList @Shermano – Clement Brunet Oct 02 '19 at 18:01
  • Why do you have a `nameList` and a `scoreList` when you could have a `playerList` with a `class Player { private String name; private long score; }`, then create a `Comparator` to sort them by score values? – EpicPandaForce Oct 02 '19 at 18:07

1 Answers1

0

Make a class to represent a score/name entry:

public class ScoreEntry implements Comparable<ScoreEntry> {
    public final String name;
    public final int score;

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

    public int compareTo (ScoreEntry other){
        return Integer.signum(score - other.score);
    }
}

Then you can put these in an ArrayList. By implementing Comparable like this, you allow the list to be sorted by score.

You might also want to include a date in this class so a score made at an earlier date ranks higher than another entry with the same score. You could use System.nanoTime() to get the time as a long when the score is made.

public class ScoreEntry implements Comparable<ScoreEntry> {
    public final String name;
    public final int score;
    public final long time;

    public ScoreEntry (String name, int score, long time){
        this.name = name;
        this.score = score;
        this.time = time;
    }

    public int compareTo (ScoreEntry other){
        if (score == other.score)
            return Long.signum(other.time - time);
        return Integer.signum(score - other.score);
    }
}

Edit: If you want to sort by some other means, you need a custom Comparator. I adapted this from this answer, which takes capitalization into account.

Comparator<ScoreEntry> nameComparator = new Comparator<>(){
    public int compare(ScoreEntry first, ScoreEntry second) {
        int res = String.CASE_INSENSITIVE_ORDER.compare(first.name, second.name);
        if (res == 0)
            res = first.name.compareTo(second.name);
        return res;
    }
}

Then you would pass this to the sort method:

Collections.sort(scoresList, nameComparator);
Tenfour04
  • 83,111
  • 11
  • 94
  • 154
  • in my ArrayList, how can I access to the score or the name after adding a ScoreEntry value ? And .add(new ScoreEntry(....)); is the good way to add values ? Thanks (Sorry I am new in development) – Clement Brunet Oct 02 '19 at 19:45
  • That's a fine way to add them. To get the first one: `list.get(0).score`, for example. – Tenfour04 Oct 02 '19 at 20:04
  • I just found how to do it, but thank you very much, and sorry but can you show me with code to sort the ArrayList by putting the score from highest to lowest like in my old ArrayList with only scores @Tenfour04 – Clement Brunet Oct 02 '19 at 20:17
  • Same code you were already using, but swap in the new list's name. `Collections.sort(scoresList, Collections.reverseOrder());` – Tenfour04 Oct 02 '19 at 20:31
  • thanks again, last question, is it possible to sort this same ArrayList in the alphabetical order of the names of the players, from a to z ? Thanks – Clement Brunet Oct 02 '19 at 20:51
  • You can create a Comparator and pass it to `Collections.sort()`. I made the class a Comparable above, so its "natural order" is to be sorted by score. But a custom Comparator can be used to sort it some other way. I added an explanation above. – Tenfour04 Oct 03 '19 at 12:50
  • Thanks for everything, you help me a lot, good luck for the future and thank you again – Clement Brunet Oct 03 '19 at 20:02