在嵌套循环中更改静态类变量的值

时间:2013-12-26 03:51:34

标签: java loops object static instance

我遇到了在嵌套循环中更改类变量值的问题 - 我无法弄清楚原因。我猜是因为变量是静态。但它是一个静态方法,因为它用于从文件中列出系统中的用户,它必须是静态的(我从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对象的实例,但必须使其成为非静态的并尝试在方法中创建对象的实例。如果是这样 - 我该怎么做?

4 个答案:

答案 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对象的实例化以及对象和方法是静态的是一个问题。我不得不重写一些主要问题的幕后方法。感谢您的帮助! =)