我有一个对象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;
}
}
答案 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 }
答案 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等类。