繁体   English   中英

当我尝试添加ArrayList元素时,即使它是新的,为什么我的程序仍然存在?

[英]Why does my program say the ArrayList element exists when I try to add it even though it's new?

我正在将元素添加到ArrayList中,并且它设计为在用户尝试添加预先存在的元素时显示错误(与尝试删除不存在的元素相同)。 从显示的内容来看,它添加了新元素,但仍然说该元素与ArrayList中已经存在的元素匹配。 我一直在忽略什么? ArrayList是在FacebookUser.java类中创建和操纵的。 谢谢(如果这是一个愚蠢的错误,我会提前致歉)。

DriverClass.java

public class DriverClass {

    public static void main(String[] args) {

        FacebookUser fu0 = new FacebookUser("Samuel", "password1");
        FacebookUser fu1 = new FacebookUser("Michael", "password2");
        FacebookUser fu2 = new FacebookUser("Amy", "password3");
        FacebookUser fu3 = new FacebookUser("Eugene", "password4");
        fu0.setPasswordHint("p1");
        fu3.setPasswordHint("p4");

        fu0.friend(fu1);
        fu0.friend(fu2);
        fu0.friend(fu3);
        fu0.friend(fu3);

        System.out.println(fu0.getFriends());

        fu0.defriend(fu1);
        fu0.defriend(fu1);

        System.out.println(fu0.getFriends());

        fu0.getPasswordHelp();
        fu3.getPasswordHelp();
    }

}

FacebookUser.java

import java.util.ArrayList;

public class FacebookUser extends UserAccount {

    private String passwordHint;
    private ArrayList<FacebookUser> friends = new ArrayList<FacebookUser>();

    public FacebookUser(String username, String password) {
        super(username, password);
        friends = new ArrayList<FacebookUser>();
    }

    @Override
    public void getPasswordHelp() {
        System.out.println("Password Hint: " + passwordHint);

    }

    void setPasswordHint(String hint) {
        passwordHint = hint;
    }

    void friend(FacebookUser newFriend) {
        System.out.println(friends.size());
        if (friends.size() == 0) {
            friends.add(newFriend);
        } else {
            for (int i = 0; i < friends.size(); i++) {
                if (friends.get(i).equals(newFriend)) {
                    System.out.println("That person is already in your friends list.");
                    break;
                } else if (!friends.get(i).equals(newFriend) && i == friends.size() - 1) {
                    friends.add(newFriend);
                }
            }
        }
    }

    void defriend(FacebookUser formerFriend) {
        if (friends.size() == 0) {
            System.out.println("That person is not in your friends list.");
        } else {
            for (int i = 0; i < friends.size(); i++) {
                if (friends.get(i).equals(formerFriend)) {
                    friends.remove(i);
                    break;
                } else if (!friends.get(i).equals(formerFriend) && i == friends.size() - 1) {
                    System.out.println("That person is not in your friends list.");
                }

            }
        }

    }

    ArrayList<FacebookUser> getFriends() {
        ArrayList<FacebookUser> friendsCopy = new ArrayList<FacebookUser>();
        for (int i = 0; i < friends.size(); i++) {
            friendsCopy.add(friends.get(i));
        }
        return friendsCopy;
    }

}

UserAccount.java

public abstract class UserAccount {

    private String username;
    private String password;
    private boolean active; 

    public UserAccount(String username, String password) {
        this.username = username;
        this.password = password;
        active = true;
    }

    public boolean checkPassword(String password) {
        if (password.equals(this.password)) {
            return true;
        } else {
            return false;
        }
    }

    public void deactivateAccount() {
        active = false;
    }

    public String toString() {
        return username;
    }

    public boolean checkActive() {
        if (active == true) {
            return true;
        } else {
            return false;
        }
    }

    public abstract void getPasswordHelp();

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((username == null) ? 0 : username.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        UserAccount other = (UserAccount) obj;
        if (username == null) {
            if (other.username != null)
                return false;
        } else if (!username.equals(other.username))
            return false;
        return true;
    }

}

执行:

0
1
That person is already in your friends list.
2
That person is already in your friends list.
3
That person is already in your friends list.
[Michael, Amy, Eugene]
That person is not in your friends list.
[Amy, Eugene]
Password Hint: p1
Password Hint: p4

您的循环是错误的:

for (int i = 0; i < friends.size(); i++) {
    if (friends.get(i).equals(newFriend)) {
        System.out.println("That person is already in your friends list.");
        break;
    } else if (!friends.get(i).equals(newFriend) && i == friends.size() - 1 ) {
        friends.add(newFriend);
    }
}

您要遍历好友列表,然后在到达末尾时将其添加,然后好友列表将变成一个较大的列表,然后将其与刚才添加的列表进行比较,并说该列表已经存在。

你要这个:

boolean alreadyThere = false;
for (int i = 0; i < friends.size(); i++) {
    if (friends.get(i).equals(newFriend)) {
         System.out.println("That person is already in your friends list.");
         alreadyThere = true;
         break;
    }
}

if(!alreadyThere) {
    friends.add(newFriend);
}

更简单地说,可能是这样的:

if(friends.contains(newFriend)) {
     System.out.println("That person is already in your friends list.");
} else {
     friends.add(newFriend);
}

您正在与for循环中的size()进行比较,即使您也有可能在循环中将项目添加到列表中,因此最终还是在上一次迭代时将项目与自身进行比较。

for (int i = 0; i < friends.size(); i++) { // result of size() will change
   if (friends.get(i).equals(newFriend)) {
      System.out.println("That person is already in your friends list.");
      break;
   } else if (!friends.get(i).equals(newFriend) && i == friends.size() - 1) {
      friends.add(newFriend);
   }
}

您可以只提取调用size()的结果,以便在添加新项目时它不会改变。 或者,您也可以在添加项目后退出循环。

节省尺寸:

int size = friends.size();
for (int i = 0; i < size; i++) {
   if (friends.get(i).equals(newFriend)) {
      System.out.println("That person is already in your friends list.");
      break;
   } else if (!friends.get(i).equals(newFriend) && i == friends.size() - 1) {
      friends.add(newFriend);
   }
}

或者,可能更好的方法是,一旦决定应添加项目,请使用break

for (int i = 0; i < friends.size(); i++) {
   if (friends.get(i).equals(newFriend)) {
      System.out.println("That person is already in your friends list.");
      break;
   } else if (!friends.get(i).equals(newFriend) && i == friends.size() - 1) {
      friends.add(newFriend);
      break;
   }
}

然后,一个更好的解决方案可能是避免循环并使用contains代替:

void friend(FacebookUser newFriend) {
    System.out.println(friends.size());
    if (friends.contains(newFriend)) {
        System.out.println("That person is already in your friends list.");
        return;
    }

    friends.add(newFriend);
}

您的方向是正确的,但是最后一个添加的朋友的迭代就是问题所在。

快速修复可能会在添加以下内容后打破循环:

friends.add(newFriend);
break;

但这不是一个适当的解决方案。 我们可以在这里使用contains

if (friends.contains(newFriend)) {
    System.out.println("That person is already in your friends list.");
    return;
}
friends.add(newFriend);

当您将newFriend添加到列表中时,它的大小会增加,因此循环将实际执行newFriend与自身的比较,从而再执行一次,从而显示消息。

快速的解决方法是添加一个中断。 但这使事情变得很复杂...

对我来说,你可以写:

if (friends.contains(newFriend)) {
    System.out.println("That person is already in your friends list.");
} else {
    friends.add(newFriend)
}

无需在列表元素上手动循环。

但是,甚至更简单的解决方案是为FacebookUser实现equals / hashCode(无论如何,要正确使用contains和找到合适的朋友,都需要使用equals / hashCode),并使用Set of friends而不是list。 Set结构始终确保没有重复项,如果有很多朋友,执行起来会更快。

private Set<FacebookUser> friends = new HashSet<FacebookUser>();

[...]

if (!friends.add(newFriend)) {
   System.out.println("That person is already in your friends list.");
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM