Permanent collections in Java - java

According to my assignment which asks to develop a small-scale Student Accommodation Management System :
The application should be developed using object-oriented concepts using Student class and Apartment class, implementing the appropriate data fields and methods for the classes. Data may be stored in collections i.e. array of objects, vectors, etc. or into data files except a database.
So far, I have worked with Sets. I am not sure if it the right way but I added HashSets to my classes. Example:
public static Set<Apartment> listOfApartments = new HashSet<Apartment>();
// in Apartment Class)
Now that I just realized I actually need persistent collections or some solutions to actually store the data permanently.
Any Suggestions?

If I where you I would use something such as an ArrayList to store data, especially students. Sets do not allow duplicate data so this could cause problems down the line.
With regards to persisting your data, you should take a look at the ObjectOutputStream to store your objects and to the ObjectInputStream to load them back into your application. You can take a look here for an ObjectStreams tutorial.
What I would recommend though is to use something such as XStream (you can see how to use it here). This will allow your application to store data in a human readable way (which is helpful for debugging) and will also allow your data to be read by different programming languages.

If Appartment is Serializable, then Set<Apartment> is also Serializable and doens't require any extra work to persist it using java.io classes
To make a class Serializable, you must :
make it implement the interface java.io.Serializable
add a default constructor
It is that easy

Related

How to implement save/load functionality of Java application data/state?

I have an application of POJOs (plain old java objects) representing my data.
While running, the application manipulates and remembers data as desired.
Now I want to implement a save/load feature.
I am NOT asking about basic file I/O.
I am NOT asking whether ObjectOutputStream exists.
Options I have found are those such as:
1) JSON/XML/YAML libraries such as Gson, Jackson
2) Roll your own binary file format marking everything as Serializable with a Serialization Proxy pattern.
Option 1 is unsuitable because my data model can feature cyclic references. Gson resulted in a stack overflow.
Option 2 is unsuitable because the files should be cross platform and independent of JVM; it should work on desktop and android java.
A properties file is also obviously unsuitable due to the complexity of the model.
Please do not attack my use case; my data model is perfectly well designed. The example may not be.
I will now give example code of the kind of structure that needs to be saved.
class Application {
//This College is my top level object. It could correspond to an individual save file.
College college = new College();
//I would love to be able to just throw this guy into a file.
SomeLibrary.writeToFile(college);
//And read another back.
College college2 = SomeLibrary.readFromFile(anotherCollege);
}
class College {
//The trees are implemented recursively, so this is actually just the root of each tree.
Tree<Course> artCourseTree;
Tree<Course> engineeringCourseTree;
Tree<Course> businessCourseTree;
List<Student> maleStudents;
List<Student> femaleStudents;
}
class Course {
//Each course only has 2 students in this example. Ignore.
Student student1;
Student student2;
List<Exam> examsInCourse;
LocalDate courseStartDate;
Period duration;
}
class Student {
String name;
List<Exam> listOfExamsTaken;
}
class Exam {
Student studentTakingIt;
LocalDate dateTaken;
BigDecimal score;
}
As you can see, Exams are intended to be the atomic object in this model at the bottom of the hierarchy. However, not only are they referenced by both Students and Courses, but they also refer back up to a Student and contain nonprimitives such as LocalDate and BigDecimal. The model is given meaning by referencing different subsets of Exams in different Courses and Students.
I need to save the relationships, the arrangement of these things, an arbitrary number of these things, as well as the data they hold.
What hope do I have of saving and loading such a model?
What options are there to implement a save/load feature on such a model, with such constraints?
Is it really industry standard for every java program to roll its own binary file format and create a monstrous apparatus to serialize and deserialize everything? It's that or JSON? What am I missing here? Do I have to just snapshot the VM somehow? Why is there not a standard practice for this?
Circular references is a common use case and can be handled by providing #JsonManagedReference or #JsonBackReference. Check out this SO answer for more details. Another option is to implement custom serializer and solve circular references by yourself. Here is the example for the same.
However, do consider the following aspects before going ahead with using files as database
You will have to manage concurrent writes by yourself. If not correctly handled might result in corruption/loss of the data because files are not ACID compliant by nature.
The solution is not scalable as file size will grow. Time to serialize and deserialize will increase proportionately.
You won't be able to query easily on the data stored in the file. You will always have to deserialize data first and then query on POJOs.
I'll highly recommend checking SQLite which is small, fast, self-contained, high-reliability, full-featured, SQL database engine.

How to associate an object with the quantity of that object

I am working on a Java application and came across a general implementation/meta question and wanted to reach out for suggestions.
I am looking to associate a Java object with a quantity. The java object is complex. In my case, it is a serializable object that represents JSON data from a 3rd party API. I am looking to associate a quantity with this complex Java object.
As this may be something that is easier to understand with an example, here is one. Say I have a Car class that is used to represent a car. It contains all the details of what make a car a car and is a general form that can be used to communicate over an API. Say I am making an inventory app for a dealership. The dealership would want to know how many of each Car they have. Hence the need for the association.
Ideas
There are some ways I can think of the do this.
Class it out
One idea would be to create classes that capture this association. One could have an InventoryEntry class that contains a Car and a quantity. Your dealerships inventory would then consist of a List of InventoryEntry objects.
Arrays
One can also implement this association via an Array mechanism. This can be done by creating an ArrayList<Car> for the cars and an ArrayList<Integer> for the quantity. The index for each list would be used to associate the two.
Would you recommend one of these method or some other implementation?
Using ArrayList makes it a little bit easier to start out, but if you are going to maintaining and extending this application, creating a custom class will save you a lot of time in the long run. The reason is that it would be difficult to change the ArrayList class. Yes, you could subclass the arraylist class, and override the methods that you need to, but that is making more work for yourself.
For the basic scenario that you gave, creating a CarInventory class could be extended for new behavior. The new class could just wrap a basic ArrayList or HashMap implementation, but being able to extend your application for long term maintainability is important.

Java Object Clone (additional class member) using Prototype, Builder Pattern

It is not easy to explain my issue.
JPA creates some complex objects for calculations, which are stored in a database.
We decided to set the results in a working copy of this objects.
This means for each object model we created a seperated working copy model file with the same fields but some other LocalDates values and new result fields.
When the calculation was starting the working copies are instantiated.
This approach is not the best i think.
I think of the prototype pattern to clone the object.
There i come to the problem how to add the new fields. How?
Instantion costs and ist creates lots of additionals model class files.
I only think of put the result field in the calculation data models as transient fields.
Maybe inner class or local class?
I also tried to use an interface as data bucket.
But thats not the realy purpose of interfaces and also it works only with many curious trick.
For Unit Tests and user input i think it is the best to use the builder pattern and then tell JPA to store the parent object, or not?
Sorry but my answer was to long for a comment :(
There is big complex object relationship with Lists and Sets One To Many etc. relationship. When i set the result i a new class i cant determine the right object e.g. in a list. So we bild the same structurefor these result and seperated these classes in a package. Maybe it is possible to dont build the structure a second time with also references to the "basic classes". It should be sufficient to reference to each basic class a result class. It would only a little bit more navigation to get values from deeper classes. For a similiar use case there must be a best practise, or? Interfaces or sth. I very dislike the many classes for the result. Is it not possible to clone and add classmember to it for the result or to logical group easier or something like this?
It could be a solution for somebody:
http://help.eclipse.org/luna/index.jsp?topic=%2Forg.eclipse.jdt.doc.isv%2Freference%2Fapi%2Forg%2Feclipse%2Fjdt%2Fcore%2FIWorkingCopy.html
Here you will work with the Eclipse API and create IWorkingCopies.
For the described task toooo much.

Use of Serializable other than Writing& Reading object to/from File

In Which Cases it is a good coding practice to use implements serializable other than Writing & Reading object to/from file.In a project i went through code. A class using implements serializable even if in that class/project no any Writing/Reading objects to/from file?
If the object leaves the JVM it was created in, the class should implement Serializable.
Serialization is a method by which an object can be represented as a sequence of bytes that includes the object's data as well as information about the object's type and the types of data stored in the object.
After a serialized object has been written into a file, it can be read from the file and deserialized that is, the type information and bytes that represent the object and its data can be used to recreate the object in memory.
This is the main purpose of de-serialization. To get the object information, object type, variable type information from a written(loosely speaking) representation of an object. And hence serialization is required in the first place, to make this possible.
So, whenever, your object has a possibility of leaving the JVM, the program is being executed in, you should make the class, implement Serializable.
Reading/Writing objects into files (Memory), or passing an object over internet or any other type of connection. Whenever the object, leaves the JVM it was created in, it should implement Serializable, so that it can be serialized and deserialized for recognition once it enters back into another/same JVM.
Many good reads at :
1: Why Java needs Serializable interface?
2: What is the purpose of Serialization in Java?
Benefits of serialization:
To persist data for future use.
To send data to a remote computer using client/server Java technologies like RMI , socket programming etc.
To flatten an object into array of bytes in memory.
To send objects between the servers in a cluster.
To exchange data between applets and servlets.
To store user session in Web applications
To activate/passivate enterprise java beans.
You can refer to this article for more details.
If you ever expect your object to be used as data in a RMI setting, they should be serializable, as RMI either needs objects Serializable (if they are to be serialized and sent to the remote side) or to be a UnicastRemoteObject if you need a remote reference.
In earlier versions of java (before java 5) marker interfaces were good way to declare meta data but currently we having annotation which are more powerful to declare meta data for classes.
Annotation provides the very flexible and dynamic capability and we can provide the configuration for annotation meta deta that either we want to send that information in byte code or at run time.
Here If you are not willing to read & write object then there is one purpose left of serialization is, declare metadata for class and if you are goint to declare meta data for class then personally I suggest you don't use serialization just go for annotation.
Annotation is better choice than marker interface and JUnit is a perfect example of using Annotation e.g. #Test for specifying a Test Class. Same can also be achieved by using Test marker interface.
There is one more example which indicate that Annotations are better choice #ThreadSafe looks lot better than implementing ThraedSafe marker interface.
There are other cases in which you want to send an object by value instead of by reference:
Sending objects over the network.
Can't really send objects by reference here.
Multithreading, particularly in Android
Android uses Serializable/Parcelable to send information between Activities. It has something to do with memory mapping and multithreading. I don't really understand this though.
Along with Martin C's answer I want to add that - if you use Serializable then you can easily load your Object graph to memory. For example you have a Student class which have a Deportment. So if you serialize your Student then the Department also be saved. Moreover it also allow you -
1. to rename variables in a serialized class while maintaining backwards-compatibility.
2. to access data from deleted fields in a new version (in other words, change the internal representation of your data while maintaining backwards-compatibility).
Some frameworks/environments might depend upon data objects being serializable. For example in J2EE, the HttpSession attributes must be serializable in order to benefit from Session Persistence. Also RMI and other dark ages artifacts use serialization.
Therefore, though you might not immediately need your data objects to be serializable, it might make sense to declare Serializable just in case (It is almost free, unless you need to go through the pain of declaring readObject/writeObject methods)

Transfer of a Java Serialized Object

Is it possible to declare an instance of a serializable object in one Java program / class, then repeat the definitions of the internal objects in a different program /class entirely, and load in a big complex object from a data file? The goal is to be able to write an editor for items that's kept locally on my build machine, then write the game itself and distribute it to people who would like to play the game.
I'm writing a game in Java as a hobbyist project. Within my game, there's an a family of classes that extend a parent class, GameItem. Items might be in various families like HealingPotion, Bomb, KeyItem, and so on.
class GameItem implements Serializable {
String ItemName
String ImageResourceLocation
....}
What I want to do is include definitions of how to create each item in a particularly family of items, but then have a big class called GameItemList, which contains all possible items that can occur as you play the game.
class GameItemList implements Serializable {
LinkedList<GameItem>gameItemList;
//methods here like LookUpByName, LookUpByIndex that return references to an item
}
Maybe at some point - as the player starts a new game, or as the game launches, do something like:
//create itemList
FileInputStream fileIn = new FileInputStream("items.dat");
ObjectInputStream in = new ObjectInputStream(fileIn);
GameItemList allItems = (GameItemList)in.readObject();
in.close();
//Now I have an object called allItems that can be used for lookups.
Thanks guys, any comments or help would be greatly appreciated.
When you serialize an object, every field of the object is serialized, unless marked with transient. And this behavior is of course recursive. So yes, you can serialize an object, then deserialize it, and the deserialized object will have the same state as the serialized one. A different behavior would make serialization useless.
I wouldn't use native serialization for long-term storage of data, though. Serialized objects are hard to inspect, impossible to modify using a text editor, and maintaining backward compatibility with older versions of the classes is hard. I would use a more open format like XML or JSON.
Yes, that is possible. If an object is correctly serialized, it can be deserialized in any other machine as long as the application running there knowns the definition of the class to be deserialized.
This will work, but Java serialization is notorious for making it hard to "evolve" classes -- the internal representation is explicitly tied to the on-disk format. You can work around this with custom reader / writer methods, but you might consider a more portable format like JSON or XML instead of object serialization.

Categories