首页 > 解决方案 > 在 Java 中处理未知数量的对象

问题描述

我在编程时经常遇到的一个问题是如何处理未知数量的对象。通过处理我的意思是引用它们,操纵它们等。至于我,这将是在开发较小的游戏和程序时。

目前我正在开发一个记分程序,它应该显示球员的姓名、他们的分数以及其他各种特征。此外,应该有两个按钮可以允许从得分表中添加和删除玩家,这就是我将在这里重点介绍的内容。它可能看起来像这样:

//A very limited version of my program
import java.awt.*;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

class Application extends JFrame implements ActionListener{

    //Fields, variables and components
    Container mainCont = getContentPane();      //Main container, the window itself
    private JPanel buttonPanel;
    private JPanel namePanel;
    private JButton addPlayerButton;
    private JButton removePlayerButton;
    //...
    //Many more components

    public Application(){

        //Basic window initiation
        setTitle("Score Keeper");
        this.setSize(650, 700);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainCont.setBackground(Color.BLACK);
        this.setContentPane(mainCont);

        buttonPanel = new JPanel();
        namePanel = new JPanel();

        addPlayerButton = new JButton();
        addPlayerButton.addActionListener(this);
        buttonPanel.add(addPlayerButton);

        removePlayerButton = new JButton();
        removePlayerButton.addActionListener(this);
        buttonPanel.add(removePlayerButton);

        this.add(buttonPanel);
        this.add(namePanel);
        this.setVisible(true);

        //Other code omitted for now
        //Includes other graphic components, layout managers etc.

    }

    /*
    * Action-Listener. 
    * Performs an event on an action.
    */
    @Override
    public void actionPerformed(ActionEvent event){

        if(event.getSource() == addPlayerButton){
            Application.Player newPlayer = this.new Player();    //Creates a new object, i.e. a new player
            //See below for Player class
        }

        if(event.getSource() == removePlayerButton){
            //******
            // This is where the problem lies
        }

    }

    //I use a nested class to create a new player
    public class Player{

        //Components etc.

        private String name;
        private JLabel nameLabel;

        public Player(){

            name = getName();
            nameLabel = new JLabel(name);
            namePanel.add(nameLabel);


        }

        public String getName(){
            //This basically gets input from the user to assign a name to the new player
            //Code omitted for now

        }

    }

}

到目前为止一切都很好。该程序基本上只有两个按钮,其中 addPlayerButton 添加了一个播放器对象,该播放器对象的名称显示在屏幕上。每次按下此按钮时,屏幕上都会添加一个新玩家。这可以无限次地进行。

当我们想要移除一个玩家时,问题就来了。我们怎么能做到这一点?我们不能通过名称引用它,因为所有玩家对象实际上都是匿名的。

当然,另一种选择是预先定义固定数量的玩家对象:

class Application extends JFrame implements ActionListener{

    //Fields, variables and components
    Container mainCont = getContentPane();      //Main container, the window itself
    private JPanel buttonPanel;
    private JPanel namePanel;
    private JButton addPlayerButton;
    private JButton removePlayerButton;

    private Player player1;
    private Player player2;
    private Player player3;
    //...
    //Etc.

然后我们将能够直接寻址每个玩家对象,但这太不切实际了。我们不能添加超过预定义数量的玩家,如果我们想要更少的玩家,我们有一堆从未使用过的玩家对象。此外,我们必须对每个玩家的每次启动进行硬编码——每个 nameLabel 都必须手动添加到屏幕等。

请分享您如何处理此类问题以及如何处理未知数量的对象的知识。感谢您抽出宝贵的时间和帮助!

PS 我对这个论坛还是很陌生。请让我知道这个问题是否有什么我可以改变的等等。我做了我的研究,发现以前没有解决这个问题的问题,但如果有一个我错过了,请随时让我知道!

编辑1:好的。有很多很棒的答案。我选择了使用 hashmaps 作为正确的解决方案,因为我认为这是我提供的场所的最佳解决方案。我实际解决问题的方法是,我在播放器对象中添加了一个 JButton,它删除了存储在其中的播放器对象。我还放弃了为播放器使用嵌套类的概念,而是在单独的类中实现了它. 不过,我总体上学到的是,在处理对象并且您不知道对象的数量时,通常最好将它们存储在某种集合中。我的首选是 Hashmap,因为它提供了一种基于其属性(如字符串名称或类似名称)访问对象的简单方法。

标签: javaobject

解决方案


您可以使用 Map/Hashmap,每次创建玩家时,将其添加到地图中。

您还必须改变从直接在屏幕上绘制玩家,可能会更改为在地图中绘制所有玩家,这样当玩家从地图中移除时,它将不再被绘制。

你会做这样的事情:

    Map<String, Player> map = new HashMap<>();
    map.put(player.Name, player);

然后您将在该哈希图中绘制所有内容。要删除,您只需提供要删除的播放器的名称。

    map.remove(player.Name);

当然,然后您会稍微更改代码以渲染地图内的所有内容,我相信您需要一种方法来知道要删除哪个玩家,您可能需要添加一个文本字段来输入要成为的玩家的名称删除。


推荐阅读