2013-12-26 2 views
0

У меня возникла проблема с изменением значений переменной класса внутри вложенных циклов - я не могу понять, почему. Я предполагаю, что это потому, что переменная static. Но это статический метод, и поскольку он используется для перечисления пользователя в системе из файла, он должен быть статичным (я вызываю его из основного метода для чтения файла в 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,8-2-a book,Author,Authorson,1234567890123,another book,Author,Authorson,23456789-1-a returned book,Author,Authorson,3456789

Что я в надежде получить при печати выше линии:

Current Loans: 
1. a book by Author Authorson (1234567890123) 
2. another book by Author Authorson (23456789) 

Returned Loans: 
1. a returned book by Author Authorson (3456789) 

Что я в настоящее время получать:

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 (3456789) 
a returned book by Author Authorson (3456789) 

Который ведет меня поверить, что я на самом деле не могу сделать экземпляры моего статического объекта книги, но должен сделать это не статическим и пытаться создавать экземпляры объекта в методе , Если да - как это сделать?

+0

Вы пытались отлаживать свой код и действительно видеть, что происходит в пошаговом застое? –

+0

Конечно, вы ** не можете ** создавать * экземпляры * статических объектов, вот в чем разница между статическими и нестационарными. Статический объект принадлежит самому классу. –

ответ

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 и с объектами и методами, являющимися статическими. Мне пришлось переписать несколько методов за кулисами, которые были серьезными проблемами. Спасибо за помощь! =)

1

Отсюда трудно понять, как вы можете понимать столько, сколько вы делаете, и все же быть таким смущенным, в то же время. Я не имею в виду это, чтобы быть оскорбительным - просто сказать, что я совсем не уверен, что понимаю, где вы.

Создайте экземпляры с помощью new. Таким образом, в ваших двух циклах, где вы переписываете одну статическую книгу, вместо этого вам нужна локальная переменная, которой вы назначаете книгу new, а затем установите поля.

0

Проблема не в том, что ваша книга статична, проблема в том, что она является одним и тем же объектом каждый раз, когда вы меняете ее во время цикла. Это происходит потому, что вы объявили его как статическое поле, но вы ошибаетесь, думая так, как вы об этом.

Давайте упростим задачу и вместо книги, использовать для иллюстрации:

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

Даже при создании нового экземпляра объекта Book в каждом из циклов я все равно получаю те же результаты. Я считаю, что это связано с тем, что мои два for-loops вложены в цикл while, поэтому я продолжаю редактировать один и тот же экземпляр объектной книги, поскольку он встроен в цикл while. Поэтому каждый раз создается новый экземпляр. Я прав? –

+0

@JerriKangasniemi Если вы не вызываете 'новую книгу' внутри цикла for, то вы не создаете новую. Если ваш новый код выглядит как мое редактирование, и вы * * создаете новый объект для каждого 'put', тогда у вас может быть другая проблема. В этом случае я предлагаю отладку с точкой останова, вставленной перед циклом while. Например, возможно, ваши индексы с разбивкой по строкам неверны, и вам нужно посмотреть, что на самом деле хранится в каждой книге. – Radiodef

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]); 
+0

Даже при создании нового экземпляра объекта Book я получаю те же результаты. Я считаю, что это связано с тем, что мои два for-loops вложены в цикл while, поэтому я продолжаю редактировать один и тот же экземпляр объектной книги, поскольку он встроен в цикл while. Поэтому каждый раз создается новый экземпляр. Я прав? –

+0

Да, вы правы. – Malav

+0

Теперь проверьте редактирование выше. Ответ, если вы работаете или нет с этим изменением? – Malav

Смежные вопросы