indexOf始终返回-1

时间:2017-01-22 14:21:11

标签: java listview arraylist

我有一个对象User的arraylist,其中包含用户的用户名和密码。我已经创建了updateUsername方法来尝试更改用户的用户名,其中我使用了indexOf,但它总是返回-1(它可以&# 39;在arraylist中找到所述用户。)

updateUsername方法:

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);
}

单击按钮时,在控制器中调用此方法:

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是一个单独的控制器中的列表视图 - 我已经在单独的控制器中实例化了这些:

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

不要认为这些是必要的,但我也在这里添加了getAllUsers()synToFile()getUser()方法:

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;
}

注意:我在updateUsername()方法中添加了调试行 - ArrayList是应该的,并且用户对象也是正确的。

用户类:

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;
}
}

5 个答案:

答案 0 :(得分:2)

您应该覆盖equals课程中的User方法。 indexOf方法在内部使用equals来查看数组中的每个元素是否等于输入参数。

请参阅this答案,了解如何在Java中覆盖equals

答案 1 :(得分:1)

这是User类的工作版本:

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;
    }

}

我在equals()方法中仅添加了用户名测试,但您也可以根据自己的要求添加其他测试。

答案 2 :(得分:0)

IndexOf 方法使用等于来验证列表中是否存在对象...

所以 USER 类必须正确覆盖该方法(也是hascode)

这就是为什么返回的索引为-1,即使用户对象在列表中也是如此..

这里是实现

229     public int indexOf(Object o) {
230         if (o == null) {
231             for (int i = 0; i < size; i++)
232                 if (elementData[i]==null)
233                     return i;
234         } else {
235             for (int i = 0; i < size; i++)
236                 if (o.equals(elementData[i]))
237                     return i;
238         }
239         return -1;
240     }

refernce

答案 3 :(得分:0)

除非覆盖equals,否则两个对象只有在相同的对象时才相等。在你的情况下,你假设他们有相同的username。更好的方法是使用Map代替列表,并使用String作为密钥,但这会使User类成为冗余。

// Username to password
public Map<String, String> getAllUsers() {
    try (Stream stream = Files.lines(datafilePath)) {
       return stream
              .map(line -> line.split(";"))
              .collect(Collectors.toMap(l -> l[0], l -> l[1]));
}

// to update the user
Map<String, String> userToPasswordMap = getAllUsers();
String password = userToPasswordMap.remove(oldUsername);
if (password == null) // error
userToPasswordMap.put(newUsername, password);
syncToFile(userToPasswordMap);

答案 4 :(得分:-1)

您需要覆盖用户类中的equals才能在indexOf()方法中工作(如注释中所述)。

一个例子就是。

        public class User {
        String username;
        String password;

        @Override
        public boolean equals(Object obj) {
            if (obj == null) {
                return false;
            }
            if (!User.class.isAssignableFrom(obj.getClass())) {
                return false;
            }

            final User other = (User) obj;

            if ((this.username == null) ? (other.username != null) : !this.username.equals(other.username)) {
                return false;
            }
            if (!this.password.equals(other.password)) {
                return false;
            }
            return true;
        }
    }

如评论中所述,IndexOf()不使用哈希码,我知道这与问题无关,但是覆盖两种方法(equals和hashcode)是常规的,因为你会遇到其他问题如果你不覆盖它,可以使用HashMap或HashSet等类。