Search code examples
javaarraylistranking

creating new ArrayList with elements from another one


I'm writing the code of my first Java game right now and I have a problem with ArrayList. I have one, with elements like nicknames and scores, to be specific I create it from the text file(code below):

static ArrayList<String> results = new ArrayList<String>();
BufferedReader br = new BufferedReader(new FileReader(ranking));
        String line = br.readLine();
        results.add(line);

while(line != null) {
    line = br.readLine();
    results.add(line);
}

br.close();

So the file looks like this:

nick1
score1
nick2
score2
...

I would like to make a ranking with top 10 best results, my idea is to make the class with the fields nick and score and somehow assign that fields to appriopriate ones from the ArrayList. Maybe I can do this like this:(?)

for(int i = 0;i<results.size();i=i+2){
    nick = results.get(i);
}

for(int i = 1;i<results.size();i=i+2){
    score = results.get(i);
}

Then I would create a new ArrayList, which would be in the type of that new class. But my problem is that I don't exactly know how I can connect values from 'old' ArrayList with the paramaters of future type of new ArrayList. The new one should be like:

static ArrayList<Ranking> resultsAfterModification = new ArrayList<Ranking>();
Ranking rank = new Ranking(nick, score);

Then I can easily compare players' scores and make a solid ranking.


Solution

  • You can create a class Player that contains the name and score of each player. The Player class should implement the Comparable interface which is Java's way of figuring out the logical order of elements in a collection:

    public class Player implements Comparable<Player>
    {
        private String _name;
        private double _score;
    
        public Player(String name, double score)
        {
            this._name = name;
            this._score = score;
        }
    
        public String getName()
        {
            return this._name;
        }
    
        public double getScore()
        {
            return this._score;
        }
    
        // Since you probably want to sort the players in
        // descending order, I'm comparing otherScore to this._score.
        @Override
        public int compareTo(Player otherScore) 
        {
            return Double.compare(otherScore._score, this._score);
        }
    
        @Override
        public String toString()
        {
            return "Name: " + this._name + ", Score: " + Double.toString(this._score);
        }
    }
    

    Once you've created the Player class, you can read both name and score in one go and use the Collections utility class to sort the Player list. Last but not least, you could grab the top ten by using the subList method: (this assumes that the file will have a score for each name and the file will be in the format you specified above)

    public static void main(String[] args)
    {
        List<Player> results = new ArrayList<Player>();
        BufferedReader br;
        try 
        {
            br = new BufferedReader(new FileReader("myFile.txt"));
            String line = br.readLine();
            while(line != null)
            {
                String name = line;
                double score = Double.parseDouble(br.readLine());
                results.add(new Player(name, score));
                line = br.readLine();
            }
            br.close();
        } 
        catch (FileNotFoundException e) 
        {
            e.printStackTrace();
        } 
        catch (IOException e) 
        {
            e.printStackTrace();
        }
    
        // Sort using the java.util.Collections utility class
        // Sorting will modify your original list so make a copy
        // if you need to keep it as is.
        Collections.sort(results);
        // Top 10
        List<Player> top10 = results.subList(0, 10);
    }