Backing Up Objects

  • Follow


This seems to me to be an issue in dealing with pointers and cloningobjects.  I understand that if I have two Objects, whether they'resomething like a String or an object I define myself, then when I do:String newString = oldString;that newString is simply a pointer to oldString so if I change the value inone, I change the value in the other.What I'd like to do is copy an object I've created that has a few HashMapsin it to an entirely new object and make sure they are both separate. Whenever the data in this program is saved, a backup copy of this objectwould be created.  That way, while I'm editing data in the program, if Imake a mistake, I can easily restore things to the last time I saved bycopying the back up object to the new object.This object is essentially a data table and I have several of them, storedin a Vector.  I've read that if I use clone() on a Vector, that a newVector is created, but the new one will still point to all the same objectsin the first Vector.  If I iterate through the Vector and clone each Objectin it and store each cloned object in a new Vector, will that new Vectorhave a copy of equivalent values without them being the same objects?  If that doesn't work, how can I create a backup of an Object so I can changethe values in one while the values in the other stay the same?Thanks!Hal
0
Reply hal310 (107) 7/9/2007 5:38:13 AM

Hal Vaughan <hal@thresholddigital.com> writes:>String newString = oldString;  If this is compilable, then �oldString� is the a name of a  variable that contains a reference value. When this is  executed, the other variable (named �newString�) will contain  a copy of this reference value. But no object will be  altered in the course of this action.>how can I create a backup of an Object  This depends on the circumstances. There are �shallow� copies  only copying the fields and �deep� copies, where the fields  are altered to refer to copies of subobjects (recursively),  and there are mixtures. Only you can know, what is appropriate  for your requirements. By this knowledge, you can implement  the operation as a method.  Means to copy often are a �copy constructor� or the method �clone�.  You might look up these subjects in the technical literature.
0
Reply ram 7/9/2007 10:11:14 AM


Hal Vaughan writes:> String newString = oldString;> > that newString is simply a pointer to oldString so if I change the value in> one, I change the value in the other.Ironically, under most circumstances it is not possible to change the value of a String, so this made a bad example.  Strings are "immutable"; without resorting to evil reflection trickery their value cannot be changed after construction.  An example using "Foo" instead of "String" would be valid (one would assume Foo is not immutable).  However, the main point of the post is valid, that assignment copies references, not objects.>> how can I create a backup of an ObjectStefan Ram wrote:>   This depends on the circumstances. There are »shallow« copies>   only copying the fields and »deep« copies, where the fields>   are altered to refer to copies of subobjects (recursively),>   and there are mixtures. Only you can know, what is appropriate>   for your requirements. By this knowledge, you can implement>   the operation as a method.> >   Means to copy often are a »copy constructor« or the method »clone«.>   You might look up these subjects in the technical literature.Hal Vaughan writes:>> This object is essentially a data table and I have several of them, stored>> in a Vector.  I've read that if I use clone() on a Vector, that a newWhy did you use the senescent Vector class in lieu of, say, ArrayList or any other List (or more generic Collection) class?  Vector is, what, seven or eight years out of date, and dangerous?  If you need synchronized methods, Collections.synchronizedList( yourList ) is much safer than Vector.-- Lew
0
Reply Lew 7/9/2007 12:25:58 PM

On Mon, 09 Jul 2007 01:38:13 -0400, Hal Vaughan<hal@thresholddigital.com> wrote, quoted or indirectly quoted someonewho said :>String newString = oldString;>>that newString is simply a pointer to oldString so if I change the value in>one, I change the value in the other.No.  All you can do is make newString point to a different string.OldString and all the references pointing to it are the same.What you are describing is a char[].If you change it, it changes for all references pointing to it.--Roedy Green Canadian Mind ProductsThe Java Glossaryhttp://mindprod.com
0
Reply Roedy 7/9/2007 7:13:17 PM

Lew wrote:
> Hal Vaughan writes:
>> String newString = oldString;
>>
>> that newString is simply a pointer to oldString so if I change the 
>> value in
>> one, I change the value in the other.
> 
> Ironically, under most circumstances it is not possible to change the 
> value of a String, so this made a bad example.  Strings are "immutable"; 
> without resorting to evil reflection trickery their value cannot be 
> changed after construction.  An example using "Foo" instead of "String" 
> would be valid (one would assume Foo is not immutable).

One would assume "String" is immutable:

   public class String {
     public java.lang.String value;
     public String toString() { return value; }
   }


piotr
0
Reply pikob (132) 7/9/2007 8:31:45 PM

Lew wrote:> Hal Vaughan writes:>> String newString = oldString;>>>> that newString is simply a pointer to oldString so if I change the >> value in>> one, I change the value in the other.> > Ironically, under most circumstances it is not possible to change the > value of a String, so this made a bad example.  Strings are "immutable"; > without resorting to evil reflection trickery their value cannot be > changed after construction.  An example using "Foo" instead of "String" > would be valid (one would assume Foo is not immutable).One would assume "String" is mutable:   public class String {     public java.lang.String value;     public java.lang.String toString() { return value; }   }piotr
0
Reply Piotr 7/9/2007 8:35:19 PM

Hal Vaughan writes:>>> String newString = oldString;>>>>>> that newString is simply a pointer to oldString so if I change the >>> value in>>> one, I change the value in the other.Lew wrote:>> Ironically, under most circumstances it is not possible to change the >> value of a String, so this made a bad example.  Strings are >> "immutable"; without resorting to evil reflection trickery their value >> cannot be changed after construction.  An example using "Foo" instead >> of "String" would be valid (one would assume Foo is not immutable).Piotr Kobzda wrote:> One would assume "String" is mutable:> >   public class String {>     public java.lang.String value;>     public java.lang.String toString() { return value; }>   }You're just being argumentative.Absent any specific disclaimer to the contrary, as the original post was, why in the world would one figure that "String" meant anything other than "java.lang.String"?  If you wish to assume the OP is an idiot who reuses the most fundamental class names, thus damaging maintenance, then perhaps, and only perhaps, your point would have a micro-skootch of merit, but I refuse to believe the OP was that stupid.Be real.-- Lew
0
Reply Lew 7/9/2007 11:53:58 PM

Lew wrote:> Hal Vaughan writes:>>>> String newString = oldString;>>>>>>>> that newString is simply a pointer to oldString so if I change the>>>> value in>>>> one, I change the value in the other.> > Lew wrote:>>> Ironically, under most circumstances it is not possible to change the>>> value of a String, so this made a bad example.  Strings are>>> "immutable"; without resorting to evil reflection trickery their value>>> cannot be changed after construction.  An example using "Foo" instead>>> of "String" would be valid (one would assume Foo is not immutable).> > Piotr Kobzda wrote:>> One would assume "String" is mutable:>> >>   public class String {>>     public java.lang.String value;>>     public java.lang.String toString() { return value; }>>   }> > You're just being argumentative.> > Absent any specific disclaimer to the contrary, as the original post was,> why in the world would one figure that "String" meant anything other than> "java.lang.String"?  If you wish to assume the OP is an idiot who reuses> the most fundamental class names, thus damaging maintenance, then perhaps,> and only perhaps, your point would have a micro-skootch of merit, but I> refuse to believe the OP was that stupid.> > Be real.I may be self taught and, because of that, have missed quite a few of thebasics (like the issue about others lists being better than vectors), but Ican assure you the OP is NOT that stupid.Dense and stubborn, maybe, but not that stupid.Hal(The O.P.)
0
Reply Hal 7/10/2007 1:03:01 AM

OK, it's high time *someone* answered the OP's question here.If you want to do a full deep copy of a data structure, just serializeand deserialize it. If you want to, to a RAM buffer rather than a(possibly temporary) disk file. (The TCP/IP loopback interface isanother intriguing possibility.) As an added bonus feature, if youserialize to a .bak file on disk you get a disk backup that can berestored later by deserializing it, e.g. after a program abend.You need to make the stuff you use in this data structureserializable. The standard collection classes already areserializable. The Java Tutorial on Sun's Web site has furtherinformation about serialization for beginners.
0
Reply Twisted 7/10/2007 3:38:22 AM

Twisted wrote:> OK, it's high time *someone* answered the OP's question here.> > If you want to do a full deep copy of a data structure, just serialize> and deserialize it. If you want to, to a RAM buffer rather than a> (possibly temporary) disk file. (The TCP/IP loopback interface is> another intriguing possibility.) As an added bonus feature, if you> serialize to a .bak file on disk you get a disk backup that can be> restored later by deserializing it, e.g. after a program abend.> > You need to make the stuff you use in this data structure> serializable. The standard collection classes already are> serializable. The Java Tutorial on Sun's Web site has further> information about serialization for beginners.Thank you!Now I have some good terms to use for searching.  I can work it out fromthere.Hal
0
Reply Hal 7/10/2007 5:34:06 AM

Lew wrote:> Hal Vaughan writes:>>>> String newString = oldString;>>>>>>>> that newString is simply a pointer to oldString so if I change the >>>> value in>>>> one, I change the value in the other.> > Lew wrote:>>> Ironically, under most circumstances it is not possible to change the >>> value of a String, so this made a bad example.  Strings are >>> "immutable"; without resorting to evil reflection trickery their >>> value cannot be changed after construction.  An example using "Foo" >>> instead of "String" would be valid (one would assume Foo is not >>> immutable).> > Piotr Kobzda wrote:>> One would assume "String" is mutable:>>>>   public class String {>>     public java.lang.String value;>>     public java.lang.String toString() { return value; }>>   }> > You're just being argumentative.No, I'm not.  My apologies to all of you who have interpreted my post that way.  That was just to show that there is other possibility (other than reflection mentioned by you) to mutate "String" value, which gives the above example similar sense as using Foo does.  That's all.> Absent any specific disclaimer to the contrary, as the original post > was, why in the world would one figure that "String" meant anything > other than "java.lang.String"?  If you wish to assume the OP is an idiot> who reuses the most fundamental class names, thus damaging maintenance, > then perhaps, and only perhaps, your point would have a micro-skootch of > merit, but I refuse to believe the OP was that stupid.I have never assumed that.  If the OP thinks I did, my apologies to him, that was not my intent.> Be real.Well, I'll try.  Thank you for advice.piotr
0
Reply Piotr 7/10/2007 8:29:19 AM

On Jul 10, 4:29 am, Piotr Kobzda <p...@gazeta.pl> wrote:> No, I'm not.  My apologies to all of you who have interpreted my post> that way.  That was just to show that there is other possibility (other> than reflection mentioned by you) to mutate "String" value, which gives> the above example similar sense as using Foo does.  That's all.Of course, it doesn't *really* mutate a "String" value, in that yourString is seen by the compiler as a different type to, and notassignable to, java.lang.String.On the other hand, there is another real way to mutate a String --alter it when it's serialized, then deserialize it.
0
Reply Twisted 7/10/2007 11:07:15 AM

Hal Vaughan wrote:> Twisted wrote:> >> OK, it's high time *someone* answered the OP's question here.>>>> If you want to do a full deep copy of a data structure, just serialize>> and deserialize it. If you want to, to a RAM buffer rather than a>> (possibly temporary) disk file. (The TCP/IP loopback interface is>> another intriguing possibility.) As an added bonus feature, if you>> serialize to a .bak file on disk you get a disk backup that can be>> restored later by deserializing it, e.g. after a program abend.>>>> You need to make the stuff you use in this data structure>> serializable. The standard collection classes already are>> serializable. The Java Tutorial on Sun's Web site has further>> information about serialization for beginners.> > Thank you!> > Now I have some good terms to use for searching.  I can work it out from> there.You will probably find Stefan's advice (the very first answer to your post) more manageable.  Serialization is a topic fraught with perils.Stefan Ram suggested:>   This depends on the circumstances. There are »shallow« copies>   only copying the fields and »deep« copies, where the fields>   are altered to refer to copies of subobjects (recursively),>   and there are mixtures. Only you can know, what is appropriate>   for your requirements. By this knowledge, you can implement>   the operation as a method.> >   Means to copy often are a »copy constructor« or the method »clone«.>   You might look up these subjects in the technical literature.The usual best is to write your own copy method(s).Serialization requires a number of steps to ensure safety, covered well by Joshua Bloch's /Effective Java/.  You need a serialVersionUID, possibly to write methods writeObject(), readObject(), readObjectNoData(), writeReplace() and readResolve(), making certain fields transient, making sure all referenced objects are also serializable, more threading concerns, possible static variable trouble, and so on.  It creates a back-door constructor and a public access to the class that must be maintained in perpetuity.Just writing a copy method is likely to be much easier.-- Lew
0
Reply Lew 7/10/2007 11:28:48 AM

Twisted wrote:> Of course, it doesn't *really* mutate a "String" value, in that your> String is seen by the compiler as a different type to, and not> assignable to, java.lang.String.Of course, my String is different type.  It simply allows to implement the scenario described by the OP:<sscce>public class Test {     public static void m(String[] args) {         class String {             java.lang.String value;             public java.lang.String toString() { return value; }         }         String oldString = new String();         String newString = oldString;  // the OP's line (literally)         oldString.value = "123";         System.out.println(newString);     }}</sscce>> > On the other hand, there is another real way to mutate a String --> alter it when it's serialized, then deserialize it.That way you cannot mutate the value of an existing String object.  It allows to create a new one only.  To achieve similar effect, much easier is to use a String's "copy constructor".piotr
0
Reply Piotr 7/10/2007 12:25:14 PM

Lew wrote:> Hal Vaughan wrote:>> Twisted wrote:>> >>> OK, it's high time *someone* answered the OP's question here.>>>>>> If you want to do a full deep copy of a data structure, just serialize>>> and deserialize it. If you want to, to a RAM buffer rather than a>>> (possibly temporary) disk file. (The TCP/IP loopback interface is>>> another intriguing possibility.) As an added bonus feature, if you>>> serialize to a .bak file on disk you get a disk backup that can be>>> restored later by deserializing it, e.g. after a program abend.>>>>>> You need to make the stuff you use in this data structure>>> serializable. The standard collection classes already are>>> serializable. The Java Tutorial on Sun's Web site has further>>> information about serialization for beginners.>> >> Thank you!>> >> Now I have some good terms to use for searching.  I can work it out from>> there.> > You will probably find Stefan's advice (the very first answer to your> post)> more manageable.  Serialization is a topic fraught with perils.I think I got confused at one point.  I was listening to advice from afriend who seemed skeptical of that.  Thanks for pointing that out.  (AndI'll point it out to my friend!)> Stefan Ram suggested:>>   This depends on the circumstances. There are �shallow� copies>>   only copying the fields and �deep� copies, where the fields>>   are altered to refer to copies of subobjects (recursively),>>   and there are mixtures. Only you can know, what is appropriate>>   for your requirements. By this knowledge, you can implement>>   the operation as a method.>> >>   Means to copy often are a �copy constructor� or the method �clone�.>>   You might look up these subjects in the technical literature.> > The usual best is to write your own copy method(s).> > Serialization requires a number of steps to ensure safety, covered well by> Joshua Bloch's /Effective Java/.  You need a serialVersionUID, possibly to> write methods writeObject(), readObject(), readObjectNoData(),> writeReplace() and readResolve(), making certain fields transient, making> sure all referenced objects are also serializable, more threading> concerns, possible static> variable trouble, and so on.  It creates a back-door constructor and a> public access to the class that must be maintained in perpetuity.Perpetuity is one thing I'm not concerned about.  All I'm doing is storing,in RAM, a copy of what I've been working with until I either save it again(in which case I need a new copy for backup) or until I exit the program.> Just writing a copy method is likely to be much easier.But if I'm writing a copy method, I have to write something that will takeeach Object I have in my class and duplicate it, which leads back to theoriginal problem: How do I make an actual copy of an object?  Are theretypes of Objects where clone() does an actual clone and create a newObject?Thanks!Hal
0
Reply Hal 7/10/2007 4:21:06 PM

On Jul 10, 12:21 pm, Hal Vaughan <h...@thresholddigital.com> wrote:> But if I'm writing a copy method, I have to write something that will take> each Object I have in my class and duplicate it, which leads back to the> original problem: How do I make an actual copy of an object?  Are there> types of Objects where clone() does an actual clone and create a new> Object?If you're just copying, say, an ArrayList of Foos where Foos are somesimple value objects that implement Cloneable, you can use a customcopying method to do it easily.If you've got a substantially more complex data structure which wouldhave a nontrivial traversal algorithm and contains an open-endedvariety of things, you're probably going to have a much easier timeusing serialization. That takes the matter of writing the traversalalgorithm and getting it right out of your hands and leaves youwithout much more to do for most of your classes than Cloneable. WithCloneable you need to tack on "implements Cloneable" and includepublic Object clone () {    super.clone();}to make "clone" public, at minimum. And you've still introduced a"backdoor constructor" of sorts.Serializability in a lot of cases just means tacking on "implementsjava.io.Serializable" and includingprivate static final long serialVersionUID = 1;and increasing this by one every time you make certain changes to theclass in question (basically any change where there was a non-transient field with a particular name and there no longer is or afield changes type other than to a supertype of the old type, and anychange where a non-transient field starts existing and cannot be null,false, or zero by default). More complex stuff is only infrequentlyneeded, e.g. a singleton should have every field transient and areadResolve method that returns the singleton instance from a staticfield if for some reason it's serializable. (A singleton value objectsuch as a Null or a NaN or an Infinity, for example, which is asubclass of some more general value type class.)
0
Reply Twisted 7/10/2007 7:33:56 PM

Twisted wrote:> On Jul 10, 12:21 pm, Hal Vaughan <h...@thresholddigital.com> wrote:>> But if I'm writing a copy method, I have to write something that will>> take each Object I have in my class and duplicate it, which leads back to>> the>> original problem: How do I make an actual copy of an object?  Are there>> types of Objects where clone() does an actual clone and create a new>> Object?> > If you're just copying, say, an ArrayList of Foos where Foos are some> simple value objects that implement Cloneable, you can use a custom> copying method to do it easily.In the long run, the data comes down to Strings.  While I have my own classthat stores them, the bottom line is I'm storing Strings that I need tocopy.> If you've got a substantially more complex data structure which would> have a nontrivial traversal algorithm and contains an open-ended> variety of things, you're probably going to have a much easier time> using serialization. That takes the matter of writing the traversal> algorithm and getting it right out of your hands and leaves you> without much more to do for most of your classes than Cloneable. With> Cloneable you need to tack on "implements Cloneable" and includeSo if it's at all complex, I'm better using serialization?  If so, there'sone aspect to this I'm not sure of.  I don't want to write the objects toanything.  I'm only storing them within the program temporarily, eitheruntil the next save or until the program ends.  From what I saw, usingserialization means writing the data to a stream.  Can that stream go to anobject and be read back from that object later?  (Instead of a stream beingwritten to a file on the drive or through a network connection?)> public Object clone () {>     super.clone();> }> > to make "clone" public, at minimum. And you've still introduced a> "backdoor constructor" of sorts.> > Serializability in a lot of cases just means tacking on "implements> java.io.Serializable" and including> private static final long serialVersionUID = 1;> > and increasing this by one every time you make certain changes to the> class in question (basically any change where there was a non-> transient field with a particular name and there no longer is or a> field changes type other than to a supertype of the old type, and any> change where a non-transient field starts existing and cannot be null,> false, or zero by default). More complex stuff is only infrequently> needed, e.g. a singleton should have every field transient and a> readResolve method that returns the singleton instance from a static> field if for some reason it's serializable. (A singleton value object> such as a Null or a NaN or an Infinity, for example, which is a> subclass of some more general value type class.)I'm not worried about changes, since any data written from one of myserializable objects would only be stored in RAM and never on disk.  Thelongest it would last would be until the program exits, so version trackingis moot (unless I've missed something important).Thanks!Hal
0
Reply Hal 7/12/2007 9:40:33 AM

Hal Vaughan wrote:> So if it's at all complex, I'm better using serialization?  If so, there's> one aspect to this I'm not sure of.  I don't want to write the objects to> anything.  I'm only storing them within the program temporarily, either> until the next save or until the program ends.  From what I saw, using> serialization means writing the data to a stream.  Can that stream go to an> object and be read back from that object later?  (Instead of a stream being> written to a file on the drive or through a network connection?)<http://java.sun.com/javase/6/docs/api/java/io/ByteArrayOutputStream.html><http://java.sun.com/javase/6/docs/api/java/io/ByteArrayInputStream.html>I still prefer copy methods to serialization.-- Lew
0
Reply Lew 7/12/2007 2:14:07 PM

Lew wrote:> Hal Vaughan wrote:>> So if it's at all complex, I'm better using serialization?  If so,>> there's>> one aspect to this I'm not sure of.  I don't want to write the objects to>> anything.  I'm only storing them within the program temporarily, either>> until the next save or until the program ends.  From what I saw, using>> serialization means writing the data to a stream.  Can that stream go to>> an>> object and be read back from that object later?  (Instead of a stream>> being written to a file on the drive or through a network connection?)> > <http://java.sun.com/javase/6/docs/api/java/io/ByteArrayOutputStream.html>> <http://java.sun.com/javase/6/docs/api/java/io/ByteArrayInputStream.html>> > I still prefer copy methods to serialization.> Okay, so how do I make copy of a String so I can modify either the copy orthe original without effecting the other?  (Yes, I know Strings followdifferent rules than other Objects, but this is a start.)I'm not ruling copying out.  I am still finishing up some other stuff andthis is a few steps off for me.  I've learned to look ahead and askquestions like this before I get to that part of my work so I have time toget answers and explore what people tell me about.Hal
0
Reply Hal 7/12/2007 2:36:49 PM

Hal Vaughan wrote:> Okay, so how do I make copy of a String so I can modify either the copy or> the original without effecting [sic] the other?  (Yes, I know Strings follow> different rules than other Objects, but this is a start.)As was pointed out a few times in this thread, you cannot modify a String's value.Neither the copy nor the original.You can copy a String a couple of ways, e.g.,    String original = "Something";    String copy = new String( original );-- Lew
0
Reply Lew 7/12/2007 10:57:36 PM

Lew wrote:> Hal Vaughan wrote:>> Okay, so how do I make copy of a String so I can modify either the copy>> or>> the original without effecting [sic] the other?  (Yes, I know Strings>> follow different rules than other Objects, but this is a start.)> > As was pointed out a few times in this thread, you cannot modify a> String's value.> > Neither the copy nor the original.That was why I was asking.  While there are other objects involved, thereare a number of Strings involved. > You can copy a String a couple of ways, e.g.,>     String original = "Something";>     String copy = new String( original );Okay, I missed the obvious.  Thanks!Hal
0
Reply Hal 7/13/2007 2:04:59 AM

On Jul 12, 6:57 pm, Lew <l...@lewscanon.nospam> wrote:> Hal Vaughan wrote:> > Okay, so how do I make copy of a String so I can modify either the copy or> > the original without effecting [sic] the other?  (Yes, I know Strings follow> > different rules than other Objects, but this is a start.)>> As was pointed out a few times in this thread, you cannot modify a String's value.>> Neither the copy nor the original.>> You can copy a String a couple of ways, e.g.,>     String original = "Something";>     String copy = new String( original );And it's pointless. Strings are immutable. Better than copying them,intern them all -- myString = myString.intern();Now duplicate Strings don't waste extra memory.Whenever you use String operations to "modify" a String you actuallymake a mutated copy of the original String; if you have myString ="foo" and then yourString = myString and then myString =myString.append("bar") you end up with myString.equals("foobar")(myString == "foobar" if you intern myString after the append) andyourString == "foo". The old version is still preserved; yourStringdid not change to "foobar". (Note that interned strings will compare== to one another and to literals, which are automatically interned,when they are equals(). Comparing interned strings can be especiallyefficient then.)Regardless, you can just copy the String references when you copy thedata structure, and the backup won't change spontaneously because ofedits to the original data structure, as long as you don't do anythingsneaky with reflection to mutate the Strings in the data structure.If it's mainly Strings you can probably also find some sensible way toexternalize it with writeExternal and read it back with readExternalin an ASCII-based (or unicode, anyway) format. This would be nicerthan serialization for this sort of data, and provides a way to bothsave to disk and (via ByteArrayFooStreams or a temporary file) backup.Some wag will no doubt now suggest externalizing as XML. XML seems tobe the current "hammer fad", which makes everything look like a nailto some people.
0
Reply Twisted 7/13/2007 2:06:05 AM

Twisted wrote:> On Jul 12, 6:57 pm, Lew <l...@lewscanon.nospam> wrote:>> Hal Vaughan wrote:>> > Okay, so how do I make copy of a String so I can modify either the copy>> > or>> > the original without effecting [sic] the other?  (Yes, I know Strings>> > follow different rules than other Objects, but this is a start.)>>>> As was pointed out a few times in this thread, you cannot modify a>> String's value.>>>> Neither the copy nor the original.>>>> You can copy a String a couple of ways, e.g.,>>     String original = "Something";>>     String copy = new String( original );> > And it's pointless. Strings are immutable. Better than copying them,> intern them all -- myString = myString.intern();> > Now duplicate Strings don't waste extra memory.> > Whenever you use String operations to "modify" a String you actually> make a mutated copy of the original String; if you have myString => "foo" and then yourString = myString and then myString => myString.append("bar") you end up with myString.equals("foobar")> (myString == "foobar" if you intern myString after the append) and> yourString == "foo". The old version is still preserved; yourString> did not change to "foobar". (Note that interned strings will compare> == to one another and to literals, which are automatically interned,> when they are equals(). Comparing interned strings can be especially> efficient then.)> > Regardless, you can just copy the String references when you copy the> data structure, and the backup won't change spontaneously because of> edits to the original data structure, as long as you don't do anything> sneaky with reflection to mutate the Strings in the data structure.> > If it's mainly Strings you can probably also find some sensible way to> externalize it with writeExternal and read it back with readExternal> in an ASCII-based (or unicode, anyway) format. This would be nicer> than serialization for this sort of data, and provides a way to both> save to disk and (via ByteArrayFooStreams or a temporary file) backup.I'll be looking into this.  I've never heard of intern() or writeExternal(). That's more I can explore. > Some wag will no doubt now suggest externalizing as XML. XML seems to> be the current "hammer fad", which makes everything look like a nail> to some people.XML would be pointless.  I'm not saving the data for longer than the programis running.  Personally I think XML is overused.Hal
0
Reply Hal 7/13/2007 3:34:22 AM

Hal Vaughan wrote:....> If that doesn't work, how can I create a backup of an Object so I can> change the values in one while the values in the other stay the same?Thanks to everyone for all the helpful replies.  I looked over everythingand tried a number of test setups, both to see what would work and to learnmore about Java in general.  Basically I was working with a class calledSedTable (the program is a setting editor, so some of the classes areprefixed by Sed) and SedRow.  Within SedTable there was a Vector namedfullTable and each element was one SedRow.  Within SedRow I had another ofmy own classes, StringHashMap (I'm avoiding generics and, for now, stickingwith what I can use in Java 1.4.2.)  I also had other data in each SedRowclass, such as a flag to show if a row had been deleted and other flags andmetadata.First I looked at alternatives to Vectors since someone mentioned there wereissues with Vectors and they're outdated.  (I don't think thread safety isa factor.  While this is a Swing interface, once a value is selected orchanged, the components are frozen until all the updates are done (which isusually too fast for the user to detect).  I changed to using ArrayLists,which took almost no coding change and made a few parts easier.  (That'sone issue to being self taught -- I learn about one thing that works anddon't know there are other structures that work even better.)In the long run I decided to serialize the objects.  I know to some thatsounds like a lot of work and it seems preferred to just create copymethods, but memory doesn't seem to be an issue from what I've measured andit took far less code to serialize the objects than to copy them.Basically I added a backup() method in SedTable that serializes theArrayList that contains all the SedRows.  Then I got an error for SedRow,but all I had to add was "implements Serializable" to the class declarationline.  While I was at it, I did the same to my StringHashMap (andshift-ctrl-o fixed the imports in Eclipse).  Then it only took a few linesof code to output the object to an OjbectOutPutStream, wrap aByteArrayOutputStream around it, and have it dump everything into a byte[]. To read it back, I just reversed it and read from the same byte[] with aByteArrayInputStream with an ObjectInputStream wrapped around it.I figured if I was going to copy it, I'd have to write a loop in SedTable togo through the ArrayList and call a copy method on each SedRow.  Then I'dhave to store the StringHashMaps and a few other objects in SedRow.  Thatwould be new code in at least 2 classes and extra code for several loopsand trying to create backup copies within classes.  Another factor, one Ididn't realize until I was trying to ride the code, was that peoplesuggested using a copy() constructor, but nobody mentioned how, when usingone, I could make sure the new class had new data and not just pointers tothe old data.  In the long run it was actually easier to serialize.  (Add 2words to several classes and just add a few lines of I/O code to store eachArrayList.)I found this link extremely helpful in using the serialization:http://java.sun.com/developer/technicalArticles/Programming/serialization/I've already tested this and am thrilled with how easily it works.Hal
0
Reply Hal 7/22/2007 7:36:40 AM

23 Replies
81 Views

(page loaded in 3.969 seconds)

Similiar Articles:


















7/12/2012 2:55:48 PM


Reply: