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

时间:2015-10-25 11:44:45

标签: java object arraylist bukkit

我有以下对象列表:

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,用户将收到一条消息,说明他输入的命令的正确用法。

4 个答案:

答案 0 :(得分:6)

Java的android:layout_gravity="center_horizontal|top" android:fitsSystemWindows="true"有一个boolean contains(Object)方法,对于希望避免重复的情况很方便:

List<T>

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(); } 是否已存在同一Object,但不关心teamname

如果joinkey不是影响相等性的对象状态的一部分,那么将它作为一个字段作为对象的一部分通常不是一个好主意。例如,如果joinkey是暂时性的,您可以使用“连接”团队与其他内容,制作joinkey,使用HashMap<String,MCWarTeam>作为地图的关键,并删除{{1}来自joinkey应该是一个好主意。

答案 1 :(得分:3)

根据说明和您对其他答案的评论,不使用List似乎是一个好主意,而是将您的数据存储在Map<String, MCWarTeam>中,将{1}}映射到{{ 1}}对象:

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(); 中实施equalshashCode,因为you aren't gonna need it;由于您的地图密钥是团队名称,containsKeyMCWarTeam个对象进行操作,这些对象已经有明确定义的Stringequals语义。

答案 2 :(得分:2)

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

 boolean exists = teamlist.contains(member);

正如@Eran提到的,HashSet会在O(1)list contains的情况下为您O(n)提供查询,唯一的问题是HashSet没有Object t允许重复。 是的,使用实际类型而不是List<MCWarTeam> teamlist = new ArrayList<>();

/* the function next_prime(count) */
unsigned int next_prime(unsigned int count) {
    /* avoid "unused parameter" warning */
    (void)count;
    /* introduce this block because defining the variable count here will read to an redeclaring error */
    {
        static unsigned int count = 0;
        int n = -1;
        /* n is given with a scanf */
        scanf("%d", &n);
        /* if n=0 */
        if (n == 0) {
            /* count value must be reset to 0 */
            count = 0;
            /* return the first prime number, 2 */
            return 2;
        } else {
            /* count the time it is called */
            count++;
            /* return the "count-th" prime number */
            return nth_prime(count);
        }
    }
}

答案 3 :(得分:2)

为了在ArrayList中搜索read()实例,您首先必须覆盖MCWarTeam,以便定义两个equals实例的含义等于彼此。然后,您可以使用MCWarTeamindexOf(team)来确定某个实例是否在contains

但是,此类搜索需要线性时间,因此List可能会更好地满足您的需求(为此,您需要覆盖HashSetequals,以及你将能够在恒定时间内找到一个物体是否在hashCode中。