【问题标题】:creating new ArrayList with elements from another one使用另一个元素创建新的 ArrayList
【发布时间】:2017-01-05 03:59:42
【问题描述】:

我现在正在编写我的第一个 Java 游戏的代码,我遇到了 ArrayList 的问题。我有一个,带有昵称和分数等元素,具体来说,我是从文本文件中创建的(代码如下):

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();

所以文件看起来像这样:

nick1
score1
nick2
score2
...

我想对前 10 名最佳结果进行排名,我的想法是使用字段 nick 和 score 来创建类,并以某种方式将这些字段分配给 ArrayList 中的适当字段。也许我可以这样做:(?)

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);
}

然后我会创建一个新的ArrayList,它的类型就是那个新类。但我的问题是我不完全知道如何将“旧”ArrayList 的值与新ArrayList 的未来类型的参数联系起来。新的应该是这样的:

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

然后我可以轻松比较玩家的分数并做出可靠的排名。

【问题讨论】:

  • 你为什么用ArrayList?用HashMap代替它,它就像键值对例如nickname1=score1,nickname2=score2.so你对它做任何操作。排序,添加,删除。跨度>

标签: java arraylist ranking


【解决方案1】:

您可以创建一个类Player,其中包含每个玩家的姓名和得分。 Player 类应该实现 Comparable 接口,这是 Java 确定集合中元素逻辑顺序的方式:

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);
    }
}

创建Player 类后,您可以一次性读取名称和分数,并使用Collections 实用程序类对Player 列表进行排序。最后但并非最不重要的一点是,您可以使用subList 方法获得前十名:(这假设文件将为每个名称都有一个分数,并且文件将采用您上面指定的格式)

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);
}

【讨论】:

  • List.subList()方法中,第二个参数:toIndex是独占的。所以要进入前 10,你应该写 results.subList(0, 10) 否则它是前 9 :)
  • 非常感谢!这就是我一直在寻找的。现在如何将该列表显示到 JLabel 中?不幸的是,这不能解决: JLabel PlayersRanking = new JLabel(); for(Player p : top10) { PlayersRanking.setText(String.valueOf(p)); }
  • @JeffTheKiller 我对摇摆不是很熟悉。我用 Java 完成的工作中有 99% 是后端或数字方面的。我浏览了本教程tutorialspoint.com/swing/swing_jlabel.htm,看起来这是一个开始的地方。如果遇到困难,您可以随时发布另一个问题。
【解决方案2】:

1) 您应该在这里通过接口编程(List 而不是声明类型中的ArrayList),因为您不使用特定于ArrayList 的方法。

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

2)

然后我将创建一个新的 ArrayList,其类型为 那个新班级。但我的问题是我不完全知道我该怎么做 将“旧”ArrayList 中的值与未来类型的参数连接起来 新的 ArrayList。

要做到这一点,您不需要进行很多更改。 你的想法有点太复杂了,因为最后你执行了两个映射:一个从读取行存储到StringList,另一个从StringList 存储到@987654330 的List @.
您可以将读取线直接映射到RankingList

   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));
         }

【讨论】:

    【解决方案3】:

    您可以将数组保存在文件中:

    1 使用 FileInputSram 和 FileOuputStream 将数组对象写入和读取到文件。

    2 使用 Gson 库将数组保存和加载为 json

    3 写为普通文本文件,如下所示: 玩家 1
    得分 1
    播放器 2
    得分 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,...);
    

    并且可以通过Arrays.sort()对数组进行排序

    【讨论】:

      【解决方案4】:

      所以你的Ranking 类可能看起来像

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

      我认为nickscore 是两个ArrayList,分别包含刻痕和分数。

      所以要创建一个普通的ArrayList,如果nickscore 的大小相同,你可以这样做。

      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);
      }
      

      现在您需要编写自己的比较器来对 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;
          }
      });
      

      【讨论】:

      • 比较你可以只返回 r1.score-r2.score;
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-29
      • 1970-01-01
      • 2017-07-01
      相关资源
      最近更新 更多