我遇到了在嵌套循环中更改类变量值的问题 - 我无法弄清楚原因。我猜是因为变量是静态。但它是一个静态方法,因为它用于从文件中列出系统中的用户,它必须是静态的(我从main方法调用它来读取文件到TreeMaps)。是否无法从方法中重写静态类变量?如果有可能 - 我到底做错了什么?
public class Loan{
protected int noOfLoans;
protected int noOfReturns;
protected User user=new User();
protected static Book book= new Book();
protected Map <Integer, Book> currentLoans=new TreeMap <Integer, Book>();
protected Map <Integer, Book> returned=new TreeMap <Integer, Book>();
protected static Map<Integer, Loan> loanList=new TreeMap<Integer, Loan>();
public static void main(String[] args){
readLoans();
}
public static void readLoans(){
loanList.clear();
BufferedReader reader = null;
try {
reader=new BufferedReader(new FileReader("loans.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
String line = null;
try {
line = reader.readLine();
} catch (IOException e) {
e.printStackTrace();
}
while (line!=null) {
String[] splitOut=line.split("-");
String[] loan_User=splitOut[0].split(",");
String[] loan_CurrentLoans=splitOut[2].split(",");
String[] loan_Returned=splitOut[4].split(",");
Loan loan = new Loan();
loan.user.setFirstName(loan_User[0]);
loan.user.setSurname(loan_User[1]);
loan.user.setPersonalID(loan_User[2]);
for (int i = 1; i <= Integer.parseInt(splitOut[1]); i++) {
book.setName(loan_CurrentLoans[((Integer.parseInt
(splitOut[1])-1)*4)]);
book.setAuthorFirstname(loan_CurrentLoans[((Integer.parseInt
(splitOut[1])-1)*4)+1]);
book.setAuthorSurname(loan_CurrentLoans[((Integer.parseInt
(splitOut[1])-1)*4)+2]);
book.setISBN(loan_CurrentLoans[((Integer.parseInt
(splitOut[1])-1)*4)+3]);
loan.currentLoans.put(i, book);
}
for (int i = 1; i <= Integer.parseInt(splitOut[3]); i++) {
book.setName(loan_Returned[((Integer.parseInt
(splitOut[3])-1)*4)]);
book.setAuthorFirstname(loan_Returned[((Integer.parseInt
(splitOut[3])-1)*4)+1]);
book.setAuthorSurname(loan_Returned[((Integer.parseInt
(splitOut[3])-1)*4)+2]);
book.setISBN(loan_Returned[((Integer.parseInt
(splitOut[3])-1)*4)+3]);
loan.returned.put(i, book);
}
loan.setNoOfLoans(Integer.parseInt(splitOut[1]));
loan.setNoOfReturns(Integer.parseInt(splitOut[3]));
loanList.put(loanList.size()+1, loan);
try {
line=reader.readLine();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
这是一个参考输入行:
John,Doe,8012311213-2-a book,Author,Authorson,1234567890123,another book,Author,Authorson,2345678901234-1-a returned book,Author,Authorson,3456789012345
我希望在上面打印时能得到什么:
Current Loans:
1. a book by Author Authorson (1234567890123)
2. another book by Author Authorson (2345678901234)
Returned Loans:
1. a returned book by Author Authorson (3456789012345)
我目前得到的是什么:
Current Loans:
1. a book by Author Authorson (1234567890123)
2. a book by Author Authorson (1234567890123)
Returned Loans:
1. a book by Author Authorson (1234567890123)
和
readLoans();
System.out.println(loanList.get(2).currentLoans.get(1).toString());
System.out.println(loanList.get(2).currentLoans.get(2).toString());
返回
a returned book by Author Authorson (3456789012345)
a returned book by Author Authorson (3456789012345)
这让我相信我实际上无法创建我的静态Book对象的实例,但必须使其成为非静态的并尝试在方法中创建对象的实例。如果是这样 - 我该怎么做?
答案 0 :(得分:1)
从这里开始,很难理解你如何能够像你一样理解,但却同时又如此困惑。我并不是说这是侮辱 - 只是说我完全不确定我知道你在哪里。
使用new
创建实例。因此,在您的两个循环中,您将覆盖一个静态书籍,而是需要一个局部变量,您可以为其分配new
书籍,然后设置字段。
答案 1 :(得分:0)
问题不在于您的Book是静态的,问题更简单,每次在循环期间更改它时它都是相同的对象。这确实发生了,因为你已经将它声明为一个静态字段,但是你正在思考你对它的看法。
让我们简化问题,而不是一本书,用这个来说明:
class AnObject {
int aValue;
}
而不是IO,只需循环几次并将其添加到列表中:
class PersistenceOfChangesDemo {
static List<AnObject> theList = new ArrayList<AnObject>();
public static void main(String[] args) {
AnObject theObject = new AnObject();
for(int i = 1; i <= 3; i++) {
/* reassign the object's value */
theObject.aValue = i;
/* adds the same object each time */
theList.add(theObject);
}
/* theList is now of size 3
* but all its elements refer to the same object (theObject) */
for(AnObject anObject : theList) {
/* prints '3' every time
* because that was the last value assigned */
System.out.println(anObject.aValue);
/* prints 'true' every time */
System.out.println(anObject == theObject);
}
}
}
解决方案是每次需要新对象时都需要创建一个新对象:
class PersistenceOfChangesDemo {
static List<AnObject> theList = new ArrayList<AnObject>();
public static void main(String[] args) {
for(int i = 1; i <= 3; i++) {
/* make a new object each time */
AnObject anObject = new AnObject();
anObject.aValue = i;
theList.add(anObject);
}
/* theList now has references to 3 different objects */
for(AnObject anObject : theList) {
/* prints 1, 2, 3 */
System.out.println(anObject.aValue);
}
}
}
根据您的评论,确保每次将其放入地图时都要创建新实例:
for (int i = 1; i <= Integer.parseInt(splitOut[1]); i++) {
Book newBook = new Book();
newBook.setName(loan_CurrentLoans[((Integer.parseInt
(splitOut[1])-1)*4)]);
newBook.setAuthorFirstname(loan_CurrentLoans[((Integer.parseInt
(splitOut[1])-1)*4)+1]);
newBook.setAuthorSurname(loan_CurrentLoans[((Integer.parseInt
(splitOut[1])-1)*4)+2]);
newBook.setISBN(loan_CurrentLoans[((Integer.parseInt
(splitOut[1])-1)*4)+3]);
loan.currentLoans.put(i, newBook);
}
答案 2 :(得分:0)
这只是参考问题。这三个都指的是同一个对象static book
,因此代表最后插入的相同细节。
更改只是创建Book()
的新对象,而不是为不同的细节使用相同的对象。
尝试以下代码
Loan loan = new Loan();
loan.user.setFirstName(loan_User[0]);
loan.user.setSurname(loan_User[1]);
loan.user.setPersonalID(loan_User[2]);
for (int i = 1; i <= Integer.parseInt(splitOut[1]); i++) {
book = new Book(); // added this line
book.setName(loan_CurrentLoans[((Integer.parseInt
(splitOut[1])-1)*4)]);
book.setAuthorFirstname(loan_CurrentLoans[((Integer.parseInt
(splitOut[1])-1)*4)+1]);
book.setAuthorSurname(loan_CurrentLoans[((Integer.parseInt
(splitOut[1])-1)*4)+2]);
book.setISBN(loan_CurrentLoans[((Integer.parseInt
(splitOut[1])-1)*4)+3]);
loan.currentLoans.put(i, book);
}
for (int i = 1; i <= Integer.parseInt(splitOut[3]); i++) {
book = new Book(); // added this line
book.setName(loan_Returned[((Integer.parseInt
(splitOut[3])-1)*4)]);
book.setAuthorFirstname(loan_Returned[((Integer.parseInt
(splitOut[3])-1)*4)+1]);
答案 3 :(得分:0)
我是如何解决的;
public static void readLoans(){
// Reads the bookList and userList.
readBooks();
readUsers();
// Creates a new BufferedReader and tries to read "loans.txt"
BufferedReader reader = null;
try {
reader=new BufferedReader(new FileReader("loans.txt"));
}
// Catches exception if "books.txt" does not exist.
catch (FileNotFoundException e) {
e.printStackTrace();
}
String line = null;
// tries to read the first line and interpret it as a String.
try {
line = reader.readLine();
}
// Catches IOexception if any is thrown when trying to read line.
catch (IOException e) {
e.printStackTrace();
}
// Loop as long as "line" is not empty, i.e. as long as a Loan is read.
while (line!=null) {
// split the String "line" at every RegEx "-"
String[] splitOut=line.split("-");
// Create a String from the first index of the first split.
String user = splitOut[0];
/* Split the second and third index of the first split and create
* new Stringarrays from them.*/
String[] loans = splitOut[1].split(",");
String[] returns = splitOut[2].split(",");
User aUser = new User();
/* Find the user in the userList whose personal ID matches the
* String "user" that we created. This is the user that we want to
* create (a) loan/s and/or (a) returned loan/s for.*/
for (int i = 1; i < userList.size()+1; i++) {
if (userList.get(i).getPersonalID().equals(user)) {
/*Set the variables for the User.*/
aUser.setFirstname(userList.get(i).getFirstname());
aUser.setSurname(userList.get(i).getSurname());
aUser.setPersonalID(userList.get(i).getPersonalID());
aUser.setTelephone(userList.get(i).getTelephone());
aUser.setLoans(userList.get(i).getLoans());
aUser.setReturns(userList.get(i).getReturns());
// Create an ArrayList for Loans and Returns for every user
ArrayList<Loan> listOfloans = new ArrayList<Loan>();
ArrayList<Loan> listOfreturns = new ArrayList<Loan>();
// if the new user has any loans...
for (int j = 0; j < aUser.getLoans(); j++) {
for (int k = 1; k < bookList.size()+1; k++) {
/* ... find the "Book" object with the
* corresponding ISBN...*/
if (bookList.get(k).getIsbn().equals(loans[j*3])) {
// ...then create a new loan object for each...
Loan loan = new Loan();
// ...and set the variables of each loan...
loan.setTitle(bookList.get(k).getTitle());
loan.setAuthor_firstname(bookList.get(k).
getAuthor_firstname());
loan.setAuthor_surname(bookList.get(k).
getAuthor_surname());
try {
loan.setIsbn(bookList.get(k).getIsbn());
} catch (Exception e) {
e.printStackTrace();
}
loan.setMaxLoan(bookList.get(k).getMaxLoan());
loan.setOnLoan(bookList.get(k).getOnLoan());
loan.setAvailable(bookList.get(k).
getAvailable());
loan.setSignature(loans[j*3+1]);
loan.setTimestamp(loans[j*3+2]);
/* ...then add each one to the "listOfloans"
* ArrayList.*/
listOfloans.add(loan);
}
}
}
/* if the "listOfloans" ArrayList is not empty,
* add the loan to loanList with User as Key.*/
if (!listOfloans.isEmpty()) {
loanList.put(aUser, listOfloans);
}
// if the new user has any returned loans...
for (int j = 0; j < aUser.getReturns(); j++) {
for (int k = 1; k < bookList.size()+1; k++) {
/* ... find the "Book" object with the
* corresponding ISBN...*/
if(bookList.get(k).getIsbn().equals(returns[j*4])){
// ...then create a new loan object for each...
Loan loan = new Loan();
// ...and set the variables of each loan...
loan.setTitle(bookList.get(k).getTitle());
loan.setAuthor_firstname(bookList.get(k).
getAuthor_firstname());
loan.setAuthor_surname(bookList.get(k).
getAuthor_surname());
try {
loan.setIsbn(bookList.get(k).getIsbn());
} catch (Exception e) {
e.printStackTrace();
}
loan.setMaxLoan(bookList.get(k).getMaxLoan());
loan.setOnLoan(bookList.get(k).getOnLoan());
loan.setAvailable(bookList.get(k)
.getAvailable());
loan.setSignature(returns[j*4+1]);
loan.setTimestamp(returns[j*4+2]);
loan.setReturndate(returns[j*4+3]);
/* ...then add each one to the "listOfreturns"
* ArrayList.*/
listOfreturns.add(loan);
}
}
}
/* if the "listOfreturns" ArrayList is not empty,
* add the returned loan to returnList with User as Key.*/
if (!listOfreturns.isEmpty()) {
returnList.put(aUser, listOfreturns);
}
}
}
// tries to read the next line and interpret it as a String.
try {
line=reader.readLine();
}
// Catches IOexception if any is thrown when trying to read line.
catch (IOException e) {
e.printStackTrace();
}
}
// try to close the BufferedReader.
try {
reader.close();
}
// Catches IOexception if any is thrown when trying to close.
catch (IOException e) {
e.printStackTrace();
}
}
Book对象的实例化以及对象和方法是静态的是一个问题。我不得不重写一些主要问题的幕后方法。感谢您的帮助! =)