从另一个班级获取一份清单

时间:2017-07-06 18:57:48

标签: java list class

我一直在试图弄清楚如何从classA中为classA创建一个List 我已经尝试创建列表的实例/对象,但是当我得到列表的大小时它总是返回空(在主类中它不是空的)。

示例:

ClassA的:

List<String> players = new ArrayList<String>();

如果我在这里使用players.size(),它将返回2例如

在ClassB中我尝试了以下内容:

 ClassA classA = new ClassA();
 List<String> newList = classA.players;
无论如何,

newList.size()总是会返回0。

我也尝试过使用吸气剂,但这似乎没什么区别。

示例:

ClassA的:

List<String> players = new ArrayList<String>();
public List<String> getList(){
    return this.players;
}

ClassB:

ClassA.getList().size()

这也将始终返回0

我该如何正确地做到这一点?我尝试使用静态,似乎工作,但我被告知:

  

“静态不是工作的正确工具。它是一种内存管理   工具,而不是访问修饰符。“

他告诉我:

  

您可以传递而不是静态而不是创建新实例   实例到其他类,通过将它们作为参数添加到   构造

然而,我并没有真正理解他的意思。如果有人能用一个令人惊奇的例子解释这一点。提前谢谢!

修改:由于很多人都没有达到我想要的地方,我会发布我的来源: 在示例中称为ClassA

public class TeamManager {

String prefix = new Messages().prefix;
List<String> players = new ArrayList<String>();
List<String> human = new ArrayList<String>();
List<String> infected = new ArrayList<String>();

void join(Player p){
    if(!players.contains(p.getName())){
        players.add(p.getName());
        teleportToLobby(p);
        for (String temp : players) {
            Bukkit.getPlayer(temp).sendMessage("§e§l"+p.getName()+ " has joined infection. §7("+players.size()+"/16)");
        }
    }else{
        p.sendMessage(prefix + "§cFailed. You are already in the game!");
    }
}
void leave(Player p){
    if(players.contains(p.getName())){
        p.teleport(Bukkit.getWorlds().get(0).getSpawnLocation());
        players.remove(p.getName());
        for (String temp : players) {
            Bukkit.getPlayer(temp).sendMessage("§7§l"+p.getName()+ " has left infection. §7("+players.size()+"/16)");
        }
    }else{
        p.sendMessage(prefix + "§cYou are not in a game!");
    }
}
void addToHumans(String playername){
    human.add(playername);
}
void removeFromHumans(String playername){
    human.remove(playername);
}
void addToInfected(String playername){
    infected.add(playername);
}
void removeFromInfected(String playername){
    infected.remove(playername);
}

void teleportToLobby(Player p){
    Location lobby = getLocFromConfig("lobby");
    if(lobby != null){
        p.teleport(lobby);
        p.sendMessage(prefix + "§aSuccessfully added to game!");
    }else{
        p.sendMessage(prefix + "§cLobby not set! Make sure to set a lobby using /infection setlobby");
    }
}
void startGame(){
    /*if(human.size() >= 4){
    }*/
    for (String temp : players) {
        Bukkit.getPlayer(temp).sendMessage("Game will start shortly!");
    }
}
Location getLocFromConfig(String locationName){
    if(Main.plugin.getConfig().get("lobby") != null){
        double x = Main.plugin.getConfig().getInt(locationName+".x");
        double y = Main.plugin.getConfig().getInt(locationName+".y");
        double z = Main.plugin.getConfig().getInt(locationName+".z");
        World world = Main.plugin.getServer().getWorld(Main.plugin.getConfig().getString(locationName+".world"));
        Location l = new Location(world, x, y, z);
        return l;
    }else{
        Bukkit.getLogger().warning("[Infection] Lobby has not been set!");
        return null;
    }
}
int getPlayersInLobby(){
    return players.size();
}

public List<String> getPlayers(){
    List<String> players = this.players;
    return players;
}
public List<String> getHumans(){
    return human;
}
public List<String> getInfected(){
    return infected;
}

}

事件类(在示例中称为ClassB)

public class Events implements Listener{

TeamManager teamman = new TeamManager();
List<String> players = teamman.getPlayers();
List<String> humans = teamman.getHumans();
List<String> infected = teamman.getInfected();
@EventHandler
public void onPlayerJoin(PlayerJoinEvent e){
    //Player p = (Player) e.getPlayer();
    //e.setJoinMessage("["+lvl+"]" + e.getPlayer().getName() +"has joined the game!");
    //p.setDisplayName("[lvl1]"+p.getName());

}
@EventHandler
public void onPlayerDamage(EntityDamageByEntityEvent  e){
    if(e.getEntity() instanceof Player){
        Player p = (Player) e.getEntity();
        Bukkit.getServer().broadcastMessage("Players: "+ players);
        if(players.contains(p.getName())){
            if((p.getHealth() - p.getLastDamage()) < 1){
                for (String temp : players) {
                    Bukkit.getPlayer(temp).sendMessage("§c"+p.getName()+" got infected by "+p.getKiller().getName()+"!");
                }
                e.setCancelled(true);
                 p.setHealth(20);
                 teamman.addToInfected(p.getName());
                 teamman.removeFromHumans(p.getName());
                 p.sendMessage("§cYou have been infected!!");
            }
        }
    }
}

}

如上所述,我希望能够从TeamManager访问列表并在事件中使用它们。正如解释players在Events类中是空的。我希望这会有所帮助。

4 个答案:

答案 0 :(得分:0)

每次你做

ClassA classA = new ClassA();
List<String> newList = classA.players;

将创建/拥有在ClassA中声明的ArrayList的新实例。

并且,因为下面的代码行是一个实例变量。因此,每个实例都有不同的副本。

List<String> players = new ArrayList<String>();

所以,解决方案是:

 ClassA classA = new ClassA();
 classA.players.add("A");
 List<String> newList = classA.players;

或者在构造函数中使用setter方法或初始化,或者将其声明为静态成员。这一切都将取决于您的要求。

  

您可以传递而不是静态而不是创建新实例   实例到其他类,通过将它们作为参数添加到   构造

这意味着您可以使用构造函数将ClassA实例传递给ClassB。

答案 1 :(得分:0)

我认为你的问题是你没有独立思考这些对象。只有在B类中初始化A类实例时,才能对该实例进行变异。

然后你可以将对象从B类传递到你想要的地方,但你不能从类a初始化类A然后直接在类B中使用它,除非你将它传递给B类

答案 2 :(得分:0)

A的列表将始终为空,因为您正在访问新实例的列表。如果要获取列表A,则已将列表A作为参数发送到B类。示例:

class ClassA{
 List<String> players; 
 ClassA(){
  players = new ArrayList<>();
 }
 public List getPlayers(){
  return this.players;
 }
}

class ClassB{
  private List<String> playersA;

  ClassB(List playersA){
   this.playersA = playersA;
 }
}

// In your main code

ClassA classA = new ClassA();
ClassB classB;
List<String> players = classA.getPlayers();
players.add("P1");
players.add("P2");

classB = new ClassB(players);

答案 3 :(得分:0)

简单的答案是您需要将您创建的ClassA实例传递给ClassB。

创建类时,将创建类定义。每次使用new关键字时,都会创建该类的新实例。假设您有足够的内存,您可以拥有任意数量的类实例。但每个实例都与其他实例分开。

就像String和List是类并且需要实例化一样,您的自定义类也可以。因此,在您的主要内容或您使用ClassA和ClassB的任何地方,您都希望将它们实例化为:

ClassA instanceOfClassA = new ClassA();
ClassB instanceOfClassB = new ClassB();

我们假设,因为你没有指明,你是在主要的那样做的。

您的目标:从ClassB中访问ClassA的特定实例列表。

您已经在ClassA中创建了getList()方法。这很好。你会使用它。

接下来,您将要在ClassB中创建类型为ClassA的数据成员,以及该成员的getter和setter:

public class ClassB {
    ...
    ClassA myInstanceOfClassA;

    public void setClassAInstance(ClassA instance){
        this.myInstanceOfClassA = instance;
    }
    public ClassA getClassAInstance(){
        return this.myInstanceOfClassA;
    }
}

然后,在您更新了ClassA实例中的players之后,以及在您实例化了上面的ClassB实例之后,返回主页:

instanceOfClassB.setClassAInstance(instanceofClassA);

然后在ClassB中,可以使用该实例访问players的列表。

List<String> playersFromClassA = myInstanceOfClassA.getList();

同样,从ClassB内部调用myInstanceOfClassA.getList().size();应返回适当数量的玩家。