检查Java中的ArrayList中是否存在对象

检查Java中的ArrayList中是否存在对象,java,object,arraylist,bukkit,Java,Object,Arraylist,Bukkit,我有以下对象列表: private List<Object> teamlist = new ArrayList<Object>(); 现在列表中的对象没有名称,但可以使用列表引用,对吗?在向列表中添加新元素之前,如何检查具有特定属性的对象是否已经存在?这是对象的构造函数: public MCWarTeam(String teamname, String joinkey){ this.teamname = teamname; this.joinkey =

我有以下对象列表:

private List<Object> teamlist = new ArrayList<Object>();
现在列表中的对象没有名称,但可以使用列表引用,对吗?在向列表中添加新元素之前,如何检查具有特定属性的对象是否已经存在?这是对象的构造函数:

public MCWarTeam(String teamname, String joinkey){
    this.teamname = teamname;
    this.joinkey = joinkey;
}
我想检查是否已经有名为teamname的团队。或者,是否有更好的方法来存储对象?以前,我只是使用HashMap添加teamname和joinkey,效果很好,但我认为使用对象是更好的方法

以下是事件处理程序的重要代码:

        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;
    }
else if(cmd.getName().equalsIgnoreCase(“createTeam”)){
如果(args.length>0&&args.length<3){
字符串joinkey=“”;
如果(参数长度>1)
joinkey=args[1];
字符串teamname=args[0];
MCWarTeam newTeam=新MCWarTeam(团队名称,joinkey);
如果(!teamlist.containsKey(teamname)){
teamlist.put(teamname,newTeam);
sender.sendMessage(“已成功创建新团队\”+teamname+“\”,加入键\+joinkey+“\”!团队:”;
sender.sendMessage(“所有团队:”);
for(字符串键:teamlist.keySet()){
sender.sendMessage(键);
}
}否则
sender.sendMessage(“团队已经存在!”);
返回true;
}
返回false;
}
else if(cmd.getName().equalsIgnoreCase(“joinTeam”)){
如果(args.length>0&&args.length<3){
字符串joinkey=“”;
如果(参数长度>1)
joinkey=args[1];
字符串teamname=args[0];
if(团队列表.containsKey(团队名称)){
字符串teamKey=teamlist.get(teamname.getJoinKey();
if(joinkey==teamKey){
temlist.get(teamname).addPlayer(playername);
Bukkit.broadcastMessage(“MCWar:+playername+”成功加入团队\“+teamname+”\”);
}否则
sender.sendMessage(“加入密钥不正确!”);
}否则{
sender.sendMessage(“团队不存在!团队:”);
for(字符串键:teamlist.keySet()){
sender.sendMessage(键);
}
}
返回true;
}
返回false;
}

基本上,如果返回false,用户将收到一条消息,解释他输入的命令的正确用法。

如果您正确地实现
MCWarTeam
equals
方法,那么
contains
应该告诉您对象是否存在

 boolean exists = teamlist.contains(member);
正如@Eran所提到的,
HashSet
将为您提供
O(1)
查找,其中
列表包含
O(n)
,唯一的一点是
HashSet
不允许重复。 是的,使用实际类型而不是
对象

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

要在ArrayList中搜索
MCWarTeam
实例,首先必须覆盖
equals
,以定义两个
MCWarTeam
实例相等的含义。然后,您可以使用
indexOf(team)
contains
来确定实例是否在
列表中

但是,这样的搜索需要线性时间,因此
哈希集
可能更适合您的需要(为此,您需要覆盖
equals
hashCode
,并且您可以在恒定时间内找到对象是否在
集中),这对于希望避免重复的情况非常方便:

if (!teamlist.contains(newTeam)) {
    teamlist.add(newTeam);
} 
MCWarTeam
类必须实现
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
对象,但不关心
joinkey


如果
joinkey
不是影响相等的对象状态的一部分,则将其作为对象的一部分作为字段通常不是一个好主意。例如,如果
joinkey
是用于将团队与其他事物“连接”起来的暂时性事物,那么制作
HashMap
,使用
joinkey
作为映射的键,并从
MCWarTeam
中删除
joinkey
应该是一个好主意。

根据描述和您对其他答案的评论,最好不要使用
列表
,而是将数据存储在
映射
中,该映射将团队名称映射到
MCWarTeam
对象中:

private Map<String, MCWarTeam> teams = new HashMap<>();
根据团队名称检索
MCWarTeam
对象,例如访问
joinKey
属性,很容易:

String joinKey = teams.get(teamName).getJoinKey();

注意,使用这种方法,您不应该在
MCWarTeam
中实现
equals
hashCode
,因为;由于您的映射键是团队名称,因此对已具有定义良好的
equals
hashCode
语义的
String
对象进行操作。

是否覆盖MCWarTeam中的
equals
?如果是这样,只需使用
List.contains
。您可能希望将列表键入
,而不是
。我也不知道你是如何认为
数组列表
在某种程度上比
HashMap
好,但我希望你是基于真实的东西,而不仅仅是直觉。读
集合
有那么难吗?对于OP来说可能是不切实际的,因为即使
包含
执行得很好,检索元素的唯一方法是通过迭代;没有
get
方法。
Map
可能是最好的选择
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
}
String joinKey = teams.get(teamName).getJoinKey();