On my program I want to save some state using stack.
But all object in stack are always the same(the lest i enterd).
here is my Save code:
public void saveState(){
state.setMatrix(temp.clone()); //temp is int[][]
state.setScore(score); //score is int
State newgaGameState = new State(state); //copy consructor
stack.push(newgaGameState);
}
I guess i need to copy the state because the stack save the reference.
How I need to do it??
what I did wrong?
thanks.
You need to use deep copy. So, you can do one of the following:
use state.clone() (of course, you have to check if it creates a deep copy)
serialize and then deserialize object you want to copy
implement this by yourself
You are adding information to state, and then you save gameState. If this is not a typo, it seems you are not really saving anything new.
Use ObjectOutputStream and ObjectInputStream;
WriteObject
FileOutputStream fout = new FileOutputStream(file-full-path);
ObjectOutputStream oos = new ObjectOutputStream(fout);
oos.writeObject(your-object);
oos.close();
Read Object
FileInputStream fin = new FileInputStream(file-full-path);
ObjectInputStream ois = new ObjectInputStream(fin);
Your-Class yourObject = (Your-Class) ois.readObject();
ois.close();
Related
I have:
ArrayList<ArrayList<ArrayList<Task>>> optimalPaths = new ArrayList<ArrayList<ArrayList<Task>>>();
I would like to create a deep copy of optimalPaths. The copy itself should contain no references whatsoever to optimalPaths. Would the following code work?
ArrayList<ArrayList<ArrayList<Task>>> altPaths = new ArrayList<ArrayList<ArrayList<Task>>>();
for (ArrayList<ArrayList<Task>> e : optimalPaths){
altPaths.add((ArrayList<ArrayList<Task>>) e.clone()); // Create deep copy of optimalPaths
}
I'm not sure if there are still references within altPaths on some level.
You may do it by yourself
for (ArrayList<ArrayList<Task>> outer : optimalPaths) {
ArrayList<ArrayList<Task>> newOuter = new ArrayList<>();
for (ArrayList<Task> inner : outer) {
ArrayList<Task> newInner = new ArrayList<>();
for (Task task: inner) {
newInner.add((Task) task.clone());
}
newOuter.add(newInner);
}
altPaths.add(newOuter);
}
You can use copy by serialization and deserialization if Task class doesnt have any transient fields that you want to copy:
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bos);
out.writeObject(optimalPaths);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream in = new ObjectInputStream(bis);
ArrayList<ArrayList<ArrayList<Task>>> copied = (ArrayList<ArrayList<ArrayList<Task>>>) in.readObject();
or use external class to do that: SerializationUtils from Apache Commons
I am creating a little GUI for a "movie manager" with Java and Swing.
I have a class MovieTableModel that extends AbstractTableModel and has the data for the rows of the table in an Object[][]data.
A second class MovieUI manages the JFrame and well, the GUI in general.
The last class MovieManager is actually just a main function to create an instance of movieui and make it visible.
Now my problem is that by now, data is "saved" in my code. I want it to be able to be loaded and saved. If there is no save-file, one should be created and I should be able to add or delete rows of it (the actionlisteners are already set up, I just need a way to handle the file).
So the GUI looks like this:
MovieManager
This is kinda what I tried:
File tabledata = new File("tabledata.class");
if (!tabledata.exists()) {
try {
tabledata.createNewFile();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
tabledata.
FileInputStream in = new FileInputStream("tabledata.class");
ObjectInputStream input = new ObjectInputStream(in);
Object data = input.readObject();
System.out.print(data);
Both didn't work - I think I do understand how this works in general, but I don't know how to make it to the data in my table, especially as it is saved as an Object[][] but the file is an Object.
And if that works out - how can I add or delete single rows?
Thanks for your help in advance! :)
If you serialize you tablemodel or the object that backs your tablemodel, then you can read it later and restore it to the JTable.
When you read the object again from the ObjectInputStream, I think you are missing the cast to the right type you are saving:
FileInputStream in = new FileInputStream("tabledata.class");
ObjectInputStream input = new ObjectInputStream(in);
Object[][] data = (Object[][])input.readObject();
After you create new file you need to write the data using ObjectOutputStream and then read it with ObjectInputStream.
Object[][] data;
//save
File tabledata = new File("tabledata.dat"); //I wouldn't use class extension (class is for compiled Java)
//creation of file omitted
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(tabledata));
out.writeObject(data);
out.close();
//load
ObjectInputStream in = new ObjectInputStream(new FileInputStream(tabledata));
data = (Object[][]) in.readObject(); //explict cast required
in.close();
Because this stores all data as one big chunk I don't think it is possible to just read/write one element. You would have to resort to counting bytes of stored objects and then skip to right position. If you would really need to store huge amount of table data I would use some relational database as backend. Otherwise I wouldn't bother with such optimization. Just rewrite everything on save.
I'm crating a client-server chat application. After discovering the C/C++ approach with sending bytes of data is a real pain in Java (signed bytes are simply hilarious), I started trying to use more convenient methods - specifically Serializable interface and ObjectOutputStream along with ByteArrayOutputStream.
This answer quite describes what I know at the moment.
So, I can convert my object into a byte array, which can then be put into output buffer that is eventually sent (the sending is done asynchronously).
Now with object, I need to send the size of the byte array first - so that the receiving function knows how much data should be read before parsing the object.
So in this code:
out = new ObjectOutputStream(bos);
out.writeObject(this);
return bos.toByteArray();
Can I somehow prepend the object size?
out = new ObjectOutputStream(bos);
out.writeObject(this);
//PSEUDO FUNCTION - beware
out.writeIntOnOffset(out.size(), 0) //Push the size on the beginning of the array
return bos.toByteArray();
Once you have object size just send it:
MyClass obj = ....;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(obj); // this is what you already have.
int size = baos.length; // now we have size
OutputStream socketStream = .... // I guess you know how to get it.
ObjectOutputStream socketOos = new ObjectOutputStream(socketStream);
socketOos.writeInt(size);
socketOos.write(baos.toByteArray());
You should definitely not mess with the array it self.
Instead you should create a separate method that returns size
I am looking to implement a HashMap with its contents in the bytecode. This would be similar to me serializing the content and then reading it in. But in my experience serialization only works with saving it to a file and then reading it in, I would want this implementation to be faster than that.
But in my experience serialization only works with saving it to a file and then reading it in, I would want this implementation to be faster than that.
Serialization works with streams. Specifically, ObjectOutputStream can wrap any OutputStream. If you want to perform in-memory serialization, you could use ByteArrayOutputStream here.
Similarly on the input side.
You can save your HashMap as byte array using Java Serialization mechanizm
Map map = new HashMap();
map.put(1, 1);
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bout);
oos.writeObject(map);
oos.close();
byte[] bytes = bout.toByteArray();
// restore from bytes
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes));
map = (Map) ois.readObject();
System.out.println(map);
output
{1=1}
not that both keys and values in the Map must be Serializable otherwise it wont work
I want to create on ObjectOutputStream, but I don't want to persist the object in a file, so how to do that? All the tutorials(that I found) say only about the file way:
FileOutputStream fos = new FileOutputStream("t.tmp");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(new Date());
oos.close();
I want to store the object into a database, so I need to specify a stream in method setBinaryStream() from class PreparedStatement.
Thanks for answering...
Store it in a byte array instead. You can use ByteArrayOutputStream for this. This way you can use PreparedStatement#setBytes().
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(new Date());
oos.close();
// ...
preparedStatement.setBytes(i, baos.toByteArray());
That said, this is pretty a good smell. Are you sure that you need to serialize Java objects into a database? This way they are unindexable and unsearchable. If you for example store each Person serialized in the DB, you cannot do SELECT * FROM person WHERE name = 'John' anymore. The normal practice is to do a 1:1 mapping of the entity and the DB table. The Date for example can perfectly be stored in a DATETIME/TIMESTAMP column.
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream os = new ObjectOutputStream(bos);
os.writeObject(new Date());
os.close();
byte[] data = bos.toByteArray();
So now you have a byte array and do what you want with it.
you specifically need to use an outputstream to write to a database? I would seriously consider looking at the persistence api before attempting to write an outputstream implementation.. since connection details etc, might get tricky to manage.
have a look at link text and remember it can be used in J2SE as well.