簡體   English   中英

檢查Java中的ArrayList中是否存在Object

[英]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();
}

我只是想檢查一個具有相同teamnameObject是否已經存在,但是不關心joinkey

如果joinkey不是影響相等性的對象狀態的一部分,那么將它作為字段作為對象的一部分通常不是一個好主意。 例如,如果joinkey是你用的東西瞬態隊“連接”到其他事情,制作HashMap<String,MCWarTeam>使用joinkey為重點,以地圖和刪除joinkeyMCWarTeam應該是一個不錯的主意。

根據描述和對其他答案的評論,不使用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實現equalshashCode ,因為您不需要它 ; 由於您的映射鍵是團隊名稱, containsKey對已經具有明確定義的equalshashCode語義的String對象進行操作。

如果正確實現MCWarTeam equals方法,那么contains應告訴您對象是否存在。

 boolean exists = teamlist.contains(member);

並且正如@Eran提到的, HashSet會給你O(1)查找,其中list containsO(n) ,唯一的是HashSet不允許重復。 是的,使用實際類型而不是Object

List<MCWarTeam> teamlist = new ArrayList<>();

為了在ArrayList中搜索MCWarTeam實例,您首先必須重寫equals ,以便定義兩個MCWarTeam實例彼此相等的MCWarTeam 然后,您可以使用indexOf(team)contains來確定實例是否在List

但是,這樣的搜索需要線性時間,因此HashSet可能更適合您的需要(為此您需要覆蓋equalshashCode ,並且您將能夠找到對象是否在Set中恆定時間)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM