creating new ArrayList with elements from another one

1.5k views Asked by At

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.

4

There are 4 answers

3
StaticBeagle On BEST ANSWER

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);
}
1
Reaz Murshed On

So your Ranking class might look like

public class Ranking {
    public String nick;
    public int score;
}

I think the nick and score are two ArrayList containing nicks and scores respectively.

So to create a common ArrayList, if the sizes of nick and score are the same, you might do something like this.

static ArrayList<Ranking> resultsAfterModification = new ArrayList<Ranking>();
for(int i = 0; i < nick.size(); i++) {
    Ranking rank = new Ranking(nick.get(i), score.get(i));
    resultsAfterModification.add(rank);
}

Now you need to write your own comparator to sort the values inside resultsAfterModification

Collections.sort(resultsAfterModification, new Comparator<Ranking>() {
    @Override
    public int compare(Ranking r1, Ranking r2) {
        if (r1.score > r2.score)
            return 1;
        if (r1.score < r2.score)
            return -1;
        return 0;
    }
});
0
Ahmad Dehnavi On

You can save array in file :

1 use, FileInputStram and FileOuputStream to write and read array object to file.

2 use Gson library to save and load array as json

3 write as normal textfile like below: Player 1
Score 1
Player 2
Score 2 ....

ArrayList<Player> list=new ArrayList();
Scanner sc=new Scanner(new File("filepath.txt"));
While(sc.hasNextLine()){
  Player p=new Player();
  p.name=sc.nextLine();
  If(sc.hasNextFloat()){
     p.score=sc.nextFloat();
     list.add(p);
  }
}
Arrays.sort(list,...);

And can sort array by Arrays.sort()

0
davidxxx On

1) You should program by Interface (List instead of ArrayList in declared type) here because you don't use methods specific to ArrayList.

List<Ranking> resultsAfterModification = new ArrayList<Ranking>();

2)

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.

To do it, you don't need many changes. Your idea a is little too complex because finally you perform two mappings : one where you store from read line to List of String and another one where you store from List of String to List of Ranking .
You can direct map read line to List of Ranking.

   List<Ranking> rankings = new ArrayList<Ranking>();
   BufferedReader br = new BufferedReader(new FileReader(ranking));

   String nick = null;
   while ( (nick = br.readLine()) != null){
           String score = br.readLine();
           rankings.add(new Ranking(nick, score));
         }