indexOf always returns -1

advertisements

This question already has an answer here:

  • Which function should I override when using indexOf() function 1 answer

I have an arraylist of object User which contains a user's username and password. I've created a updateUsername method to attempt to change a user's username, and in it I've used indexOf, but it always returns -1(it can't find said user in the arraylist).

updateUsername method:

public void updateUsername(User user, String username) {
    ArrayList<User> users = getAllUsers();
    int i = users.indexOf(user);
    user.setUsername(username);
    users.set(i,user);
    synToFile(users);
}

This method is called in a controller when a button is clicked:

public JFXListView<Label> lview2;

@FXML
void changeUsername(ActionEvent event) {
    String username = newUserField.getText();
    UserDAO theDAO = new UserDAO();
    Label lbl = lview2.getSelectionModel().getSelectedItem();
    //the items in the listview are of object label
    User u = theDAO.getUser(lbl.getText());
    theDAO.updateUsername(u,username);
    ObservableList<Label> userList = theDAO.storeUsers();
    lview2.setItems(userList);
}

lview2 is a listview in a separate controller - I've instantiated here in the separate controller:

changeUsernameController cu = (changeUsernameController)fxmlLoader.getController();
cu.lview2 = listView;

Don't think these are necessary, but I've added the getAllUsers(), synToFile() and getUser() methods here as well:

public ArrayList<User> getAllUsers() {
    Scanner sc;
    String record = null;
    String[] fields;
    ArrayList<User> users = new ArrayList<User>();

    try {
        sc = new Scanner(dataFile);
        while (sc.hasNextLine()) {
            record = sc.nextLine();
            fields = record.split(";");
            String username = fields[0];
            String password = fields[1];
            User u = new User();
            u.setPassword(password);
            u.setUsername(username);
            users.add(u);
        }
    } catch (FileNotFoundException e) {
        System.out.println("No record found!");
        //e.printStackTrace();
    }
    return users;
}

public void synToFile(ArrayList<User> userList) {
    if (userList == null) {
        return;
    }

    try {
        FileWriter out = new FileWriter(dataFile);
        for (User u: userList) {
            out.append(u.toString() + "\n");
        }
        out.close();
    }catch (IOException e) {
        e.printStackTrace();
    }
}

public User getUser(String username) {
    ArrayList<User> users = getAllUsers();
    User user = null;
    for (User u: users) {
        if (u.getUsername().equals(username)) {
            user = u;
            break;
        }
    }
    return user;
}

Note: I added debug lines in the updateUsername() method - the ArrayList is as it should be, and the user object is correct as well.

User class:

package Server;

import java.util.ArrayList;

public class User {

private String username;
private String password;
private ArrayList<Double> scoreList=new ArrayList<Double>();

public User() {

}

public String getUsername() {
    return username;
}

public void setUsername(String username) {
    this.username = username;
}

public String getPassword() {
    return password;
}

public void setPassword(String password) {
    this.password = password;
}

public String toString() {
    return username + ";" + password;
}

public String usernameString() {
    return username;
}
}


Here's the working version of the User class:

public class User {

private String username;
private String password;
private ArrayList<Double> scoreList=new ArrayList<Double>();

public User() {

}

public String getUsername() {
    return username;
}

public void setUsername(String username) {
    this.username = username;
}

public String getPassword() {
    return password;
}

public void setPassword(String password) {
    this.password = password;
}

public String toString() {
    return username + ";" + password;
}

public String usernameString() {
    return username;
}
@Override
    public boolean equals(Object obj) {
        if (obj instanceof User){
            User tmp = (User)obj;
            return tmp.getUsername().equals(getUsername());
        }
        return false;
    }

}

I added only the test on username in the equals() method, but you can also add other tests, based on your requirements.