[英]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.