2017-01-22 2 views
0

나는 사용자의 사용자 이름과 암호를 포함하는 객체 User의 arraylist가 있습니다. updateUsername 메서드를 만들어 사용자의 사용자 이름을 변경하려고 시도했으며 그 안에 indexOf을 사용했지만 항상 -1을 반환합니다 (arraylist에서 해당 사용자를 찾을 수 없음).indexOf 항상 -1을 반환합니다

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

참고 :이 필요하지만, 내가 여기뿐만 아니라 getAllUsers(), synToFile()getUser() 방법을 추가했습니다 생각하지 말고 내가 updateUsername() 방법 디버그 라인을 추가 - ArrayList에가 예상대로입니다 be이고 사용자 개체도 정확합니다.

사용자 클래스 :

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

사용자 클래스를 표시하십시오. indexOf가 색인을 찾는 방법을 이해합니까? –

+1

'User' 클래스에서'equals'을 오버라이드 했습니까? – Eran

+0

'indexOf'는'equals (Object)'를 사용합니다. 그 코드를 보여줄 수 있습니까? –

답변

1

은 사용자 클래스의 작업 버전의 구현 :

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() 방법에서 사용자 이름 만 테스트를 추가,하지만 당신은 할 수 또한 요구 사항에 따라 다른 테스트를 추가하십시오.

-1

당신은 (코멘트에 명시된)가 같이 IndexOf 내부() 메소드를 작동하려면 사용자 클래스에 등호를 오버라이드 (override) 할 필요가있다.

예가 될 수 있습니다.

 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()는 해시 코드를 사용하지 않습니다, 당신은 거 때문에 내가 그이 질문에 관련이 없습니다 알고 있지만,이 두 가지 방법을 재정의 할 규칙 (동일 및 해시) 인 코멘트했다 HashMap이나 HashSet 같은 다른 클래스에 문제가있다.

+2

주 :'indexOf'는'hashCode()'를 사용하지 않습니다 –

+0

설명해 주셔서 감사합니다. – LouizFC

2

User 클래스의 equals 메서드를 재정의해야합니다. indexOf 메서드는 내부적으로 equals을 사용하여 배열의 각 요소가 입력 매개 변수와 같은지 확인합니다.

자바에서 equals을 재정의하는 방법에 대한 답변은 this을 참조하십시오. 방법은 를 사용

+0

어떻게 무시해야합니까? – cosmo

0

같이 IndexOf는

그래서 당신의 사용자 클래스가 제대로

(너무 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 다음

+0

hashcode too ??? – CKing

+0

Hashcode는 indexOf에서 사용하지 않는 평등 검사에서만 유용합니다. –

+0

@Tom * implements *의 영어 의미를 확인하십시오. – CKing

0

equals을 오버라이드하지 않는 한, 두 객체는 ​​동일한 객체 인 경우에만 동일합니다. 당신의 경우에 그들은 동일하다고 가정하고 있습니다 username. 더 나은 방법은 목록 대신 Map을 사용하고 을 키로 사용하는 것입니다. 이렇게하면 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); 
관련 문제