views:

75

answers:

4

I'm trying to read in player data from an array list, but after 2 hours of searching and experimenting, I'm lost.

Here's the deserializing code. It's commented, but basically there should be a file with a Serialized ArrayList of Player objects. I want to deserialize that data and store it in savedPlayers, and then use savedPlayers for a few things.

What did I do wrong?

import java.io.*;
import java.util.*;

public class RoofRunnerApp {
 private Scanner in;              // Scanner to take playerName input.
 private RoofRunnerGame gameTime;
 private String filename = "gameData.txt";

 public static void main (String[] args) {
  System.out.println("WELCOME TO *ROOF RUNNER* \n");    // Welcomes user with game title.
  RoofRunnerApp myGame = new RoofRunnerApp();
 }

public RoofRunnerApp() {
 // 1) Read in name from user.
  in = new Scanner(System.in);
  System.out.print("Please enter your name: ");
  String playerName = in.next();   
 // 2) Create Player arrayList.   
  ArrayList<Player> savedPlayers = new ArrayList<Player>();
 // 3) Read in Serialized Data from file.
  try {
     ObjectInputStream input = new ObjectInputStream(new FileInputStream(filename));    // Add file name.
     savedPlayers = (ArrayList<Player>)input.readObject(); 
     input.close();
 } catch( Exception e ) {
     e.printStackTrace();
     return;
 }
  Player thisPlayer;     //thisPlayer is passed to Game class.
 // 4) if arraylist != empty -> Check for playerName and inputName match.
  ////// If there's a match -> Set thisPlayer equal to the savedPlayer, using the Player constructor.
  if(savedPlayers.length() != 0)
   for(int i = 0; i < savedPlayers.length(); i++)
    if(playerName.equals(savedPlayers.getName())){
     thisPlayer = new Player(savedPlayers[i]);
     break;
    }
  }
 else
  thisPlayer = new Player(playerName); // If no match -> Set thisPlayer to new player with playerName. 

 RoofRunnerGame gameTime = new RoofRunnerGame(thisPlayer);
}
+1  A: 

I know I'm not supposed to answer, but it's not letting me edit.

UPDATE/QUESTIONS

I haven't serialized any data, yet. Right now I'm just trying to set up the deserialization (and I was going to add in serialization after). But, in Eclipse, when I try the above I get several error messages saying that savedPlayers is not an arrayList and that length() doesn't work on it.

Here's the class code. (The code near the bottom is still in the works. My errors happen in lines 33-37:

import java.io.*;
import java.util.*;

public class RoofRunnerApp {
  private Scanner in; // Scanner to take playerName input.
  private RoofRunnerGame gameTime;
  private String filename = "gameData.txt"; // File to hold Serialized Player data.

  public static void main (String[] args) {
    System.out.println("WELCOME TO *ROOF RUNNER* \n"); // Welcomes user with game title.
    RoofRunnerApp myGame = new RoofRunnerApp();
  }

  public RoofRunnerApp() {
    // 1) Read in name from user.
    in = new Scanner(System.in);
    System.out.print("Please enter your name: ");
    String playerName = in.next();   
    // 2) Create Player arrayList.   
    ArrayList<Player> savedPlayers = new ArrayList<Player>();
    // 3) Read in Serialized Data from file.
    try {
      ObjectInputStream input = new ObjectInputStream(new FileInputStream(filename)); // Add file name.
      savedPlayers = (ArrayList<Player>)input.readObject();
      input.close();
    } catch( Exception e ) {
      e.printStackTrace();
      return;
    }
    Player thisPlayer; //thisPlayer is passed to Game class.
    // 4) if arraylist != empty -> Check for playerName and inputName match.
    ////// If there's a match -> Set thisPlayer equal to the savedPlayer, using the Player constructor.
    if(savedPlayers.length() != 0)
      for(int i = 0; i < savedPlayers.length(); i++)
        if(playerName.equals(savedPlayers[i].getName())){
          thisPlayer = new Player(savedPlayers[i]);
          break;
        }
    }
    else
      thisPlayer = new Player(playerName); // If no match -> Set thisPlayer to new player with playerName. 

    RoofRunnerGame gameTime = new RoofRunnerGame(thisPlayer);

    // After:
    // Exit code in RRG
    // 1) Add current Player to current ArrayList.
    /*
    // Create/Return player objects.
    Player p = new Player(playerObject)
    savedPlayers.add(p);
    ///// Save data to file.
    ObjectOutputStream out = null;
    try {
      out = new ObjectOutputStream( new FileOutputStream( "myfile") );  // Add filename.
      out.writeObject( savedPlayer ); //write the entire ArrayList
      out.close();
    } catch( IOException e ) {
      e.printStackTrace();
      return;
    }
    */

  }

}
oldmanstan
The code is a bit messy, I think that you will need to re-edit it. Here is how de/serialization works in Java: First your serialize the object and write it to a file. Once that you want to get the data back, you simply deserialize as you did, however, if you did not serialize the data before, the whole deserialization process will not work. Also, Eclipse gives you that error because there is no method .length() for ArrayLists, instead, you have to use the .size() method. Please check the Java API for more detailed information.
npinti
If you haven't serialized anything yet, how can you possibly be having problems with de-serialization? other than mere compilation errors.
EJP
A: 

You have to serialize out the object first before you can read it. The format used by ObjectInputStream/ObjectOutputStream is not something you can type out. As such you should with the saving of the objects first into a file, then read them in. So write a class that does the writing and reading of the List first in a class of its own and test that out to get a feel for object serialisation and some of the problems. Test things like no file present, empty file, file with corrupt data, files with a valid list with zero entries etc.

As to your current implementation where you are catching the IOException for the reading you should not printStackTrace and return, its a normal valid case as the file does not currently contain a valid list. So instead you should do nothing in the catch so that the program continues on.

You may also find that the ObjectInputStream is returning null for the savedPlayers variable and you'll want to check that case before you assign the value to the savePlayers variable in that same reading code.

Paul Keeble
A: 

I fixed the code formatting. I assume you're a bit new to java. The error you get about savedPlayers is not that it is not an ArrayList but that it is not an array. You can't index it like savedPlayers[i] but must use savedPlayers.get(i), where i is the index. Your main problem seems to be the difference between an ArrayList and an array. An array is a primitive construct, while an ArrayList is a type built on top of an array. An actual array would have a length property (note: not a method!), while ArrayList has a size() method. Look up arrays in the java tutorial.

It's considered best practice to refer to types using the most general interface that still supports what you do, in this case that would be List. If you're new to java it really helps to have the API documentation handy. Look up List and ArrayList in there. You might even use Collection if you don't really care that order is preserved here, i.e. when you output a list to disk initialise it as:

Collection<Player> players = new ArrayList<Player>();

Collection doesn't have positional access though, so stick to List if you need that.

Another tip, you're using a for-loop to iterate over all the players, but collections such as List have iterators for this. It's generally more efficient when not using an ArrayList. There is a for-loop construct that you can use to iterate over all objects in a collection:

for (Player player : players) {
  // do something with each Player
}
wds
A: 
oldmanstan