0

I have a base class named Train:

public abstract class Train {
    String serialNo;
    float weight;
    final String label;

    public Train(String serialNo, float weight, String label) {
        this.serialNo = serialNo;
        this.weight = weight;
        this.label = label;
    }

    public abstract float getCapacity();
}

And I have 2 classes implementing the abstract class(I will not include getters and setters in the code):

public class FreightTrain extends Train implements Cloneable {

    private float capacityKg;
    Vector<String> freightVector = new Vector<String>();

    public FreightTrain(String serialNo, float weight, String label) throws Exception{
        super(serialNo, weight, label);
        if (weight < 0)
            throw new Exception();
    }

    @Override
    public float getCapacity() {
        return this.capacityKg;
    }
}

And the PassengerTrain class:

public class PassengerTrain extends Train implements Cloneable {

    private float seatNo;
    Vector<String> passengerId = new Vector<String>();

    public PassengerTrain(String serialNo, float weight, String label) throws Exception{
        super(serialNo, weight, label);
        if (weight < 0)
            throw new Exception();
    }

    @Override
    public float getCapacity() {
        return this.seatNo;
    }
}

Next I have an array list ArrayList<Train> arr; which contains both: the PassengerTrain and FreightTrain. I want to create methods to write the items from arr to a file and read the data from file

Here is my attempt:

public void writeObjectInTextFile(ArrayList<Train> array) {
    Formatter f = null;
    try {
        f = new Formatter(file);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }

    for(Train train: array) {

        if(train instanceof PassengerTrain) {
            String label = train.getLabel();
            String serialNo = train.getSerialNo(); 
            float capacity = train.getCapacity();
            float weight = train.getWeight();
            float seatNo = ((PassengerTrain) train).getSeatNo();
            String passId = "";

            for(String id:((PassengerTrain) train).getPassengerId()) {
                passId += id;
            }

            f.format("%s %f %s %f %f %s", serialNo, weight, label, capacity, seatNo, passId);
        } else if(train instanceof FreightTrain) {
            String label = train.getLabel();
            String serialNo = train.getSerialNo(); 
            float capacity = train.getCapacity();
            float weight = train.getWeight();
            float capacityKg = ((FreightTrain) train).getCapacityKg();
            String freightVector = "";

            for(String freight: ((FreightTrain) train).getFreightVector()) {
                freightVector += freight;
            }

            f.format("%s %f %s %f %f %s", serialNo, weight, label, capacityKg, capacity, freightVector);
        }
    }
    f.close();
}

But I have a problem: I am unable to create a function that will read this data from the file, and return the correct ArrayList with the initial data.

What is the best and fastest way to write the array of 2 different classes deriving from a single class to a file?

And how it could be recreated?

Thank you!

Please don't my question as duplicate. I have searched for similar questions and my question is different from the ones available.

I don't know how to convert back the objects from file to their respective types. What If I have n deriving classes?

8
  • 2
    Use a better format, maybe JSON or XML - in either case you need a "marker" field which dictates the "type" of object you're the data represents Commented Jun 5, 2018 at 23:20
  • Have a look at Java Serialization. Commented Jun 5, 2018 at 23:21
  • I found now ObjectInputStream. How do I check which child class is the Object I read? Can I use instanceof? Commented Jun 5, 2018 at 23:26
  • Yes, that's how you do it. Commented Jun 5, 2018 at 23:30
  • Note: an ArrayList is not an array. Commented Jun 5, 2018 at 23:47

2 Answers 2

3

Simply have your classes implement Serializable and you'll be ready to write your objects to files (and read them back, of course) whenever you want! This includes arrays of your objects, too.

That's the 10000-foot answer above. Implementing Serializable correctly (in a way that won't come back around to bite you) is a somewhat daunting subject. However, there is plenty of literature out there that can teach you how to do it and how to avoid common pitfalls. I recommend Joshua Bloch's "Effective Java" for this, personally; he's dedicated a whole chapter or two to the subject.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks but the task is to read and write to file without serialization
2

if(train instanceof PassengerTrain) This is bad. You are completely throwing the whole purpose of inheritance and polymorphism away. Your code shouldn't care about what type the trains are.

You should use the Object serialization features of Java. Implement Serializable in your Train class and use ObjectOutputStream to write and ObjectInputStream to read the objects.

Write:

public void writeTrainsToFile(ArrayList<Train> array, String file) {
    FileOutputStream fileOutputStream = new FileOutputStream(file);

    try(ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream)){
        objectOutputStream.writeInt(array.size());
        for(Train train: array) {
            objectOutputStream.writeObject(train);
        }
    }
}

Read:

public void readTrainsFromFile(ArrayList<Train> array, String file) {
    FileInputStream fileInputStream = new FileInputStream(file);

    try(ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream)){
        int trainCount = objectInputStream.readInt();
         for (int i = 0; i < trainCount; i++) {
            array.add((Train)objectInputStream.readObject());
        }
    }
}

2 Comments

yeah but the task is to write and read from file without serialization
What do you mean "the task"? There is nothing in your questions about some task. If you have some task that restricts what you can, must and cannot do, you must mention that in your question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.