2016-06-16 10 views
-1

Ich machte eine ArrayList namens ArrayList<Arena>, wie ich ein Spigot-Plugin mache.Hinzufügen von zwei Klassen zu ArrayList <Class> füllt die Arraylist mit zwei Duplikaten

public static ArrayList<Arena> all = new ArrayList<Arena>(); 

jetzt habe ich meine Klasse und das ist die Instanciation Schritt:

public Arena(String name, int min, int max) { 
    Arena.name = name; 
    Arena.layout = "default"; 
    Arena.customName = CManager.getPlugin().getArenaConfig().getString("arenas." + name + ".custom-name"); 

    ArenaManager.addToArenaList(this); 
    ArenaManager.arenaNames.add(Arena.name); 
    Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.LIGHT_PURPLE + "[" + plugin.getPdfFile().getName() 
      + "]" + ChatColor.GREEN + " [#] (Instanciated arena " + Arena.name + ")"); 

    Arena.min = min; 
    Arena.max = max; 
    Arena.world = Bukkit.getWorld(Arena.name); 

    waiting = true; 
    starting = false; 
    game = false; 
    finished = false; 
} 

ich mit diesem scheinbar einfachen Stück Code ein Problem habe.

public static void addToArenaList(Arena a) { 
    all.add(a); 
    checkArena(a); 
} 

public static void checkArena(final Arena a) { 
    Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() { 
     public void run() { 
      if (!(all.contains(a))) { 
       Bukkit.getServer().getConsoleSender().sendMessage(
         ChatColor.LIGHT_PURPLE + "[" + plugin.getPdfFile().getName() + "]" + ChatColor.RED 
           + " [E] (Error while adding arena " + a.getArenaName() + "to list)"); 
      } else { 
       Boolean found = false; 
       for (Arena f : all) { 
        if (f.getArenaName().equals(a.getArenaName())) { 
         if (found == true) { 
          Bukkit.getServer().getConsoleSender() 
            .sendMessage(ChatColor.LIGHT_PURPLE + "[" + plugin.getPdfFile().getName() + "]" 
              + ChatColor.RED + " [E] (Duplicate found with arena " 
              + a.getArenaName()); 
          continue; 
         } 
         found = true; 
        } 
       } 
       if (found == false) { 
        Bukkit.getServer().getConsoleSender() 
          .sendMessage(ChatColor.LIGHT_PURPLE + "[" + plugin.getPdfFile().getName() + "]" 
            + ChatColor.RED + " [E] (Error while adding arena " + a.getArenaName() 
            + "to list)"); 
       } 
      } 
     } 
    }, 10L); 
} 

Aber aus irgendeinem Grund, den ich Duplikate der letzten Arena bekommen, auch hier ist die erste Stufe des Verfahrens

public void onEnable() { 
    Methods.sendColoredMessage(this, ChatColor.LIGHT_PURPLE, ("Registering Commands...."), ChatColor.YELLOW); 
    registerCommands(); 
    Methods.sendColoredMessage(this, ChatColor.LIGHT_PURPLE, ("Registering Events...."), ChatColor.YELLOW); 
    registerEvents(); 
    Methods.sendColoredMessage(this, ChatColor.LIGHT_PURPLE, ("Registering Config...."), ChatColor.YELLOW); 
    createFiles(); 
    Methods.sendColoredMessage(this, ChatColor.LIGHT_PURPLE, ("Attempting to load arenas...."), ChatColor.GOLD); 
    ArenaManager.all.clear(); 
    ArenaManager.arenaNames.clear(); 
    ArenaManager.createArenas(); 
    Methods.sendColoredMessage(this, ChatColor.AQUA, 
      (pdfFile.getName() + " has been enabled! (V." + pdfFile.getVersion() + ")"), ChatColor.GREEN); 
} 
public static void createArenas() { 
    if (plugin.getArenaConfig().getConfigurationSection("arenas") != null) { 
     int count = 0; 
     ArrayList<String> listed = new ArrayList<String>(); 
     for (String arena : plugin.getArenaConfig().getStringList("enabled")) { 
      count++; 
      Bukkit.getServer().getConsoleSender() 
        .sendMessage(ChatColor.LIGHT_PURPLE + "[" + plugin.getPdfFile().getName() + "]" 
          + ChatColor.GREEN + " [" + count + "] (Loading arena " + arena + ")"); 
      int min = plugin.getArenaConfig().getInt("arenas." + arena + ".min"); 
      int max = plugin.getArenaConfig().getInt("arenas." + arena + ".max"); 

      new Arena(arena, min, max); 
     } 
     Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.LIGHT_PURPLE + "[" 
       + plugin.getPdfFile().getName() + "]" + ChatColor.GREEN + " [A] Loaded arenas are listed below:"); 
     for (Arena a : all) { 
      if (listed.contains(a.getArenaName())) { 
       continue; 
      } 
      Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.LIGHT_PURPLE + "[" 
        + plugin.getPdfFile().getName() + "]" + ChatColor.GREEN + " [A] - " + a.getArenaName()); 
      listed.add(a.getArenaName()); 
     } 
    } else { 
     Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.LIGHT_PURPLE + "[" 
       + plugin.getPdfFile().getName() + "]" + ChatColor.RED + " [E] No arenas have been found!"); 
    } 
} 

Also, wenn ich 4 Arenen hatte und die letzte wurde EndArena genannt, in Mein Array, ich werde mit 4 Elementen enden, alle mit der gleichen Arena-Klasse EndArena. Ich habe alles versucht, und normalerweise mag ich es nicht, um Hilfe zu bitten (ich mag es, Dinge selbst zu lernen), aber das hat mich so lange geärgert, dass ich es einreichen muss.

Auch hier ist meine Arena YAML Datei

YAML Config

Antwort

3

Dies geschieht, weil man Objekte nicht korrekt verwenden.

Soweit ich Ihren Code verstanden habe, möchten Sie eine Art von Arena erstellen, einige Werte dieser Arena zuweisen und sie dann zu einem ArenaManager hinzufügen. Das ist in Ordnung. Um dies zu tun, müssen Sie Instanzvariablen verwenden, damit jede erstellte Arena ihren eigenen Namen hat. Einzigartig für diese bestimmte Instanz.

Sie verwenden statische Felder hier - die statische ist die gleiche über alle Objekte im Programm, was ist nicht das, was Sie hier benötigen (es wäre von Vorteil, wenn Sie etwas wie Arena Zähler benötigen).

finden Sie einige Beispiele:

Stellen Sie sich vor es ist wirklich einfach und naive Person-Klasse (nach Ihrem Ansatz).

public class Person { 
    private static String name; 
    public Person(String name) { 
     Person.name = name; 
    } 
} 

Wenn Sie so etwas wie tun würde: neue Person ("Adam"); neue Person ("Viktor");

Sie würden mit 2 Personen Instanzen beenden, die auf eine statische Variable zeigen, die am Ende den Wert Victor haben würde. Was wir hier sicher nicht brauchen. Um diese Funktion zu haben richtig benötigen Sie Instanzvariablen verwenden:

public class Person { 
    private String name; 
    public Person(String name) { 
     this.name = name; 
    } 
} 

Jetzt, nach unserem Beispielcode Sie 2 Personen haben würden, jeder mit unterschiedlichen Namen. Es spielt keine Rolle, wie Sie darauf zugreifen, was wirklich wichtig ist, ist, dass sie Instanzfelder sein sollten - das bedeutet, dass jede Instanz einen separaten Block im Speicher hat, um diesen Wert zu halten. Wenn das Feld statisch ist, bedeutet das einfach, dass es einen möglichen Variablenwert für alle verschiedenen Objekte gibt - jedes Mal, wenn Sie es ändern, wird es für alle anderen Objekte geändert.

So dies zusammenzufassen:

Sie Instanzfelder und nicht statische Felder verwenden sollten.In Ihrem Konstruktor haben Sie: Arena.name = name; Arena.layout = "Standard";

Diese beiden Codezeilen überschreiben immer das statische Feld in Ihrer Arena-Klasse.

In Ihrem Arena Klasse haben Sie so etwas wie (Anmerkung Schlüsselwort static):

private static String name; 

Sie haben müssen:

private String name; 

so hat jede Instanz einen eigenen Namen. Bitte lesen Sie über Instanzen und statische Felder, dies macht es viel einfacher zu verstehen! Hier ist das Beispieldokument aus den Java-Tutorials: https://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html Das Tutorial wird das alles wirklich schön abdecken!

+0

Ich bin mir nicht sicher, was Sie hier meinen. Willst du damit sagen, dass ich in meiner Klasse keine statischen Felder verwenden soll, stattdessen Methoden verwenden, um darauf zuzugreifen? –

+0

Ich kann ein wenig auf meine Antwort eingehen. Im Allgemeinen ist das statische Feld für alle Instanzen des Objekts gleich. Was Sie hier brauchen, ist das Instanzfeld - schließlich weisen Sie Werte im Konstruktor zu, die darauf hindeuten, dass Sie sie anders haben müssen. Was Sie hier tun, ist der gleiche Name für alle Arena-Instanzen, was eindeutig nicht erwünscht ist. Lassen Sie mich einige Beispiele in meiner Antwort hinzufügen :) – akakus

+0

Oh okay danke, ich warte auf die Antwort –