2016-03-05 206 views
1

我的Minecraft插件有問題。我想添加播放器的對象到列表中。在此之前,我想檢查玩家是否已經存在於我的列表中。比較列表中對象的屬性

下面的例子:

public class Player{ 

    public String playerName; 
    public int Count = 0; 

    public Player(String name){ 

     playerName = name; 
    } 
} 

這裏主要類:

public class mainClass{ 
    List<Player> = PlayerList; 
    [...] 
    if(!(*An object with attribute examplename in List exist*)){ 
     Player p = new Player("eamplename") 
     PlayerList.Add(p); 
    } 
} 
+0

'Add'應是'add'。案件事宜 –

+0

謝謝,我知道。不幸的是我使用Java和C#並且總是這樣做是錯誤的:) – Snaff

回答

2

我建議兩種方法來解決你的問題。第一個是堅持使用List的方法。

List<Foo> list = new ArrayList<Foo>(); 

    boolean hasMyItem = false; 
    String newName = "hello world"; 

    for (Foo foo : list)  // iterate over each item in the list 
    { 
     if (foo.name.equals(newName)) 
     { 
      hasMyItem = true; 
      break;   // get out of for loop 
     } 
    } 

    if (!hasMyItem) 
    { 
     list.add(new Foo(newName)); 
    } 
    else 
    { 
     // the player is already in the list ... 
    } 

在這個代碼片段中,我們遍歷列表中的所有項目,直到我們發現玩家已經存在。如果您的列表中不存在此類播放器,它將以hasMyItem的值爲false退出,在這種情況下,您會將新播放器添加到列表中。

迭代列表中的所有項目是一種常用的方法,它絕對是一件好事。但是,您可能會考慮使用另一個名爲Map<Key, Value>的數據結構。 MapKeyValue相關聯,並將它們像列表一樣存儲在Map中。

你可以認爲Map<Key, Value>作爲標籤項目。 Key是每個項目的標籤。假設你的桌子上有一堆筆記本,並且你想找到一個數學筆記。如果您知道數學筆記的獨特標籤,例如封面上的一些文本或圖像,您可以毫不費力地找到它。在你的例子中,Key將成爲用戶名,Value將成爲玩家。

Map有什麼好處?它提供了一種簡單的方法來查找您擁有的Key值。如果您使用Map,上述代碼可以更簡化。

Map<String, Foo> map = new HashMap<String, Foo>(); 

    Foo f1 = new Foo("name1"); 
    Foo f2 = new Foo("name2"); 
    Foo f3 = new Foo("name3"); 

    map.put("name1", f1); 
    map.put("name2", f2); 
    map.put("name3", f3); 

    // will return true and this if statement will be executed 
    if (map.containsKey("name1")) 
    { 
     // will be executed 
    } 

    // will return false because you don't have and this if statement will not be executed 
    if (map.containsKey("some new name")) 
    { 
     // will not be executed 
    } 

有由Map<K,V>提供其他有用的方法,其可以被發現here

作爲一個附註,每當你可以聲明每個班級成員爲private,而不是default(這是你什麼時候不指定任何內容)或public。關於爲什麼你應該這樣做有很多討論,但基本上是爲了保護你自己的代碼不受其他人的傷害。你可以很容易地搜索,但這裏有一些鏈接。 Link1Link2

我希望這可以給你一些很好的起點。

+0

Hay Matthias,謝謝你的回答。我嘗試了第一個版本,它的工作原理!謝謝。地圖聽起來很有趣,但是Value可以是一個具有許多屬性的類?如果可以,我會加註你的帖子:( – Snaff

+0

是的值可以是一個具有許多屬性的類,只要定義Map playersMap = new HashMap <>();這裏你的關鍵字是name,值是Player。 java可以有很多屬性,並且避免在使用For:each進行迭代時修改List。(http://stackoverflow.com/questions/9806421/concurrentmodificationexception-when-adding-inside-a-foreach-loop-in-arraylist) –

+0

是的,'Key'和'Value'部分都可以是任何'Class',甚至可以使用'Interface'當你聲明你的'Map'時,你可以指定你想在每個'Key '和'Value',我試圖暗示這樣一個事實,即可以通過在地圖聲明中放置一個任意的類名「Foo」來將自己的類放入「Value」部分中(注意第一行)。 – BrokenBacon

0

由於有人指出,我使用的Set是不正確的,我已經決定在另一種方法(仍在使用重載equals法)

public class Player{ 
    public String playerName; 
    public int Count = 0; 
    public Player(String name){ 
     playerName = name; 
    } 
    public boolean equals(Player p){ 
     if(this==p) return true; 
     if(this.playerName.equals(p.playerName) return true; 
     return false; 
} 

而且

public class mainClass{ 
    ArrayList playerList; 
    public static void main(String[] args){ 
     playerList = new ArrayList<Player>(); 
     Player p = new Player("eamplename"); 
     checkList(p); 
    } 
    //check Player object against list and add if not exist 
    //if desired, the returned boolean can confirm whether or not 
    //player was successfully added 
    public static boolean checkList(Player player){ 
     for(Player p : playerList){ 
      if(p.equals(player)) return false; 
     } 
     playerList.add(player); 
     return true; 
} 
+0

謝謝你的回答:)我已經找到了解決方案,但你的想法是驚人的。也許我會嘗試這一點,當我不得不改變一些東西。謝謝Calvin – Snaff

+0

'Set'是一個抽象接口,只有實現這個接口的特定類才能被實例化。例如'static Set playerList = new HashSet <>()'是有效的。如果要覆蓋從java.lang.Object繼承的默認'equals'方法,則覆蓋方法的參數必須相同,在本例中爲Object而不是Player,以便其他類型的對象可以也要進行比較。當前的equals方法被編譯器認爲是一種不同的方法,在添加到Set時不會在'e1.equals(e2)'操作中調用。 –

+0

@AdrianSohn我懷疑我的答案可能有些問題。謝謝你指出。我會堅持我現在知道的,並用不同的方法修改我的答案。 –