检查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();