[英]Check if Object exists in ArrayList in Java
我有以下對象列表:
private List<Object> teamlist = new ArrayList<Object>();
我正在向列表中添加對象,如下所示:
teamlist.add(new MCWarTeam(args[0], joinkey));
現在列表中的對象沒有名稱,但可以使用列表引用,對吧? 在向列表中添加新元素之前,如何檢查具有特定屬性的對象是否已存在? 這是Objects的構造函數:
public MCWarTeam(String teamname, String joinkey){
this.teamname = teamname;
this.joinkey = joinkey;
}
我想檢查是否已經有一個名為teamname的團隊。 或者,是否有更好的方法來存儲對象? 之前,我只是使用HashMap添加了teamname和joinkey,它運行得很好,但是使用Objects來代替它將是一種更好的方法。
以下是事件處理程序的重要代碼:
else if (cmd.getName().equalsIgnoreCase("createTeam")) {
if (args.length > 0 && args.length < 3) {
String joinkey = "";
if (args.length > 1)
joinkey = args[1];
String teamname = args[0];
MCWarTeam newTeam = new MCWarTeam(teamname, joinkey);
if (!teamlist.containsKey(teamname)) {
teamlist.put(teamname, newTeam);
sender.sendMessage("Created new team \"" + teamname + "\" with join key \"" + joinkey + "\" successfully! Teams:");
sender.sendMessage("All teams:");
for (String key : teamlist.keySet()) {
sender.sendMessage(key);
}
} else
sender.sendMessage("Team already exists!");
return true;
}
return false;
}
else if (cmd.getName().equalsIgnoreCase("joinTeam")) {
if (args.length > 0 && args.length < 3) {
String joinkey = "";
if (args.length > 1)
joinkey = args[1];
String teamname = args[0];
if (teamlist.containsKey(teamname)) {
String teamKey = teamlist.get(teamname).getJoinKey();
if (joinkey == teamKey) {
teamlist.get(teamname).addPlayer(playername);
Bukkit.broadcastMessage("MCWar: " + playername + " joined Team \"" + teamname + "\" successfully!");
} else
sender.sendMessage("Join key incorrect!");
} else {
sender.sendMessage("Team doesn't exist! Teams:");
for (String key : teamlist.keySet()) {
sender.sendMessage(key);
}
}
return true;
}
return false;
}
基本上,如果它返回false,則用戶將收到一條消息,說明他輸入的命令的正確用法。
Java的List<T>
有一個boolean contains(Object)
方法,當你想避免重復時,它很方便:
if (!teamlist.contains(newTeam)) {
teamlist.add(newTeam);
}
MCWarTeam
類必須實現equals
才能使其正常工作。 覆蓋equals
,還必須覆蓋hashCode
。
@Override
public boolean equals(Object obj) {
if (!(obj instanceof MCWarTeam)) {
return false;
}
MCWarTeam other = (MCWarTeam)obj;
return teamname.equals(other.teamname)
&& joinkey.equals(other.joinkey);
}
@Override
public int hashCode() {
return 31*teamname.hashCode()+joinkey.hashCode();
}
我只是想檢查一個具有相同
teamname
的Object
是否已經存在,但是不關心joinkey
?
如果joinkey
不是影響相等性的對象狀態的一部分,那么將它作為字段作為對象的一部分通常不是一個好主意。 例如,如果joinkey
是你用的東西瞬態隊“連接”到其他事情,制作HashMap<String,MCWarTeam>
使用joinkey
為重點,以地圖和刪除joinkey
從MCWarTeam
應該是一個不錯的主意。
根據描述和對其他答案的評論,不使用List
似乎是個好主意,而是將數據存儲在Map<String, MCWarTeam>
,它將團隊名稱映射到MCWarTeam
對象:
private Map<String, MCWarTeam> teams = new HashMap<>();
您可以添加一個團隊,檢查是否已存在具有相同名稱的團隊,如下所示:
String teamName = args[0];
if (!teams.containsKey(teamName)) {
teams.put(teamName, new MCWarTeam(teamName, joinKey));
} else {
// do what you want when the team name was already in the map
}
基於團隊名稱檢索MCWarTeam
對象(例如,用於訪問joinKey
屬性)很容易:
String joinKey = teams.get(teamName).getJoinKey();
請注意,使用這種方法,您不應該在MCWarTeam
實現equals
或hashCode
,因為您不需要它 ; 由於您的映射鍵是團隊名稱, containsKey
對已經具有明確定義的equals
和hashCode
語義的String
對象進行操作。
如果正確實現MCWarTeam
equals
方法,那么contains
應告訴您對象是否存在。
boolean exists = teamlist.contains(member);
並且正如@Eran提到的, HashSet
會給你O(1)
查找,其中list contains
是O(n)
,唯一的是HashSet
不允許重復。 是的,使用實際類型而不是Object
List<MCWarTeam> teamlist = new ArrayList<>();
為了在ArrayList中搜索MCWarTeam
實例,您首先必須重寫equals
,以便定義兩個MCWarTeam
實例彼此相等的MCWarTeam
。 然后,您可以使用indexOf(team)
或contains
來確定實例是否在List
。
但是,這樣的搜索需要線性時間,因此HashSet
可能更適合您的需要(為此您需要覆蓋equals
和hashCode
,並且您將能夠找到對象是否在Set
中恆定時間)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.