File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Java in General and the fly likes difference between changing the String after putting in Set or changing Set in Object Big Moose Saloon
  Search | Java FAQ | Recent Topics
Register / Login
JavaRanch » Java Forums » Java » Java in General
Reply Bookmark "difference between changing the String after putting in Set or changing Set in Object" Watch "difference between changing the String after putting in Set or changing Set in Object" New topic
Author

difference between changing the String after putting in Set or changing Set in Object

Amandeep Singh
Ranch Hand

Joined: Jul 17, 2008
Posts: 836
example-

if you see its output, you will not see str changes.


but if you do this way, you can see the changes in set values but not in String value. well one reason that comes into my mind is String is immutable whereas Set is mutable. So in my production changes also i followed the below steps.

Is it a kind of risky thing to do or pretty safe to do this ?





SCJP 1.4, SCWCD 5, SCBCD 5, OCPJWSD 5,SCEA-1, Started Assignment Part 2
My blog- http://rkydesigns.blogspot.com
Duc Vo
Ranch Hand

Joined: Nov 20, 2008
Posts: 254
Amandeep Singh wrote:example-
Is it a kind of risky thing to do or pretty safe to do this ?

It is risky, but it is acceptable in some cases. It is risky because the ContData doesn't have full control of its internal state, hence won't be able to ensure that its operations are consistent. So in the perfect world, such problem should not exist, however, sometime it is too expensive to implement otherwise, you just have to deal with it, just need to be aware of the problem.

Anyway, after some refactoring your ContData can be something like


So that if you want to initialise an instance of ContData, it should be something like


“Everything should be as simple as it is, but not simpler.” Albert Einstein
Amandeep Singh
Ranch Hand

Joined: Jul 17, 2008
Posts: 836
well if you look this code-



it is no different than your's except ContData.

I think as long as you see the results good in output. the possibility of riskiness should be ruled out. And my this code is in Production, it is working without the issues.
Duc Vo
Ranch Hand

Joined: Nov 20, 2008
Posts: 254
It will only be a problem if you have to debug mysterious issue later on i.e.
you change the set and the internal state of contData change without its notice.



Ah by the way, this
So that if you want to initialise an instance of ContData, it should be something like

Should read
If you change the set outside contData, it doesn't change the internal state of contData

Amandeep Singh
Ranch Hand

Joined: Jul 17, 2008
Posts: 836
Duc Vo wrote:
So that if you want to initialise an instance of ContData, it should be something like

Should read
If you change the set outside contData, it doesn't change the internal state of contData



i don't agree with this point. if we change the internal state it is definitely reflected. could you somehow can give me a scenario where it doesn't works..
Duc Vo
Ranch Hand

Joined: Nov 20, 2008
Posts: 254
Amandeep Singh wrote:
i don't agree with this point. if we change the internal state it is definitely reflected. could you somehow can give me a scenario where it doesn't works..

Didn't you try my example above?

With your version of ContData, if I add another item to the set after initialising contData object, then the item is added into internal set of contData without its notice. And it doesn't happen to my version of ContData.

In the above example, your output at line 5 will be [hello] and after changing the set at line 8, the output at line 11 is now [hello, world]. Which means the internal state of object contData has been changed without using its own operation, it actually violates the Encapsulation principle of OOD.

In my example in the second post, the output at line 7 is [hello] and even if I changed the set at line 9 the output at line 12 is still [hello].
Amandeep Singh
Ranch Hand

Joined: Jul 17, 2008
Posts: 836

In the above example, your output at line 5 will be [hello] and after changing the set at line 8, the output at line 11 is now [hello, world]. Which means the internal state of object contData has been changed without using its own operation, it actually violates the Encapsulation principle of OOD.


this is what i actually want. I am asking is this thing guaranteed to work always ? Let me know as it is an urgent issue. what is working in above quote is what i need always to work.
Duc Vo
Ranch Hand

Joined: Nov 20, 2008
Posts: 254
I think if you only run them in the same JVM, it should always work.

But it's not a good practice, and potentially will create more problems later on say a year from now and/or when other developers inherit the project.
Should you let the contData object handle the change instead?
Amandeep Singh
Ranch Hand

Joined: Jul 17, 2008
Posts: 836
even if ContData want to handle the situation. it will be eventually end up in same situation.

the only way issue resolve is-



can be changed to




do you think the above code changes does it really makes difference?
Duc Vo
Ranch Hand

Joined: Nov 20, 2008
Posts: 254
No that change doesn't make any difference. The problem isn't with the client code, the problem is with the implementation of ContData. If later on in the code the set variable is used for different purpose, the contData object will not have control of its state. The ContData should have method to add an item or collection of items, it should also provide a way to iterate through the items if the client code is required, also it should not return a reference to the set (its internal state). Recheck my implementation of the ContData in the second post.
Amandeep Singh
Ranch Hand

Joined: Jul 17, 2008
Posts: 836
oh i understand your point, you want to make the Set localized to ContData. So nobody can change it without the intent of ContData.
but the way i did is just made the Set outside the ContData. So that it can be shared outside also.

do you think there can be issues in my code, if yes which scenario ?

I just treated ContData as a placeholder of set.
Duc Vo
Ranch Hand

Joined: Nov 20, 2008
Posts: 254
Amandeep,

I did mention that there may be side effect problem and I did give example in previous posts.
Normally it should work, but if you have mysterious issue like getSet() method of ContData returns inconsistent data time to time, be aware that any one who got a hold on the set reference of ContData can change the set. If it only happen on few places in your project, then it should be managable. If it happens almost to all your objects, you should consider refactor your code base.

Hope it help,

Amandeep Singh
Ranch Hand

Joined: Jul 17, 2008
Posts: 836
well, i change the set only at one place as same as in my examples. but to get the set value, i do it at various places.
Does any one agree to this, for this particular scenario i mentioned it can give rise to problems. So far my tests are working great.
does that mean still i haven't discovered the issue.

Experts Help is appreciated!
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19216

Duc Vo wrote:Normally it should work, but if you have mysterious issue like getSet() method of ContData returns inconsistent data time to time, be aware that any one who got a hold on the set reference of ContData can change the set.

That's where the unmodifiable wrapper methods in java.util.Collections come in:
Note how my iterator() method uses the unmodifiable set returned by getSet(). That's because Iterator has a nasty method called remove() - which allows foreign code to remove elements from your set if you return set.iterator() directly!


SCJP 1.4 - SCJP 6 - SCWCD 5
How To Ask Questions How To Answer Questions
Amandeep Singh
Ranch Hand

Joined: Jul 17, 2008
Posts: 836
In my case, there is no method which is going to remove from the Set.
but with the situation i am fighting is -


but the way i did is just made the Set outside the ContData. So that it can be shared outside also. So the code outside the ContData can change the value of Set.

but the way Duc is saying- make Set localized to ContData. So nobody can change it without the intent of ContData.

Even i agree with Duc approach. but is my approach wrong. I tested my code, it works well. if you want complete posting of the code let me know. above code are just snapshots. As my code will go into production, please advise if it needs immediate intention.



Expert advice would be appreciated as per my problem...
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19216

Your code is only as flawed as the code that uses it. If in your application, there is no code at all that modifies the set - no problem. But if anybody (perhaps you in the future) decides to use that class in another project, and doesn't know the contents are shared (or willingly (ab)uses this fact), your code may not work as that person expected.
Amandeep Singh
Ranch Hand

Joined: Jul 17, 2008
Posts: 836
thanks Rob. can you suggest some changes in my code ASAP.
Amandeep Singh
Ranch Hand

Joined: Jul 17, 2008
Posts: 836
Well in real world i do have, more than 1 set types like this-



and the code use to above code is-


but i am unable to achieve the desired results. Still without the intent of ContData1, the user can changes the value of set.
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19216

If you don't want the sets edited outside your class, you will have to follow the combined techniques Duc Vo and I have shown you: copy the set in the constructor, and return an unmodifiable set wrapper:
Note that I also changed the Javadoc of the get method to inform users that they can't add anything to the returned set.

Duc Vo
Ranch Hand

Joined: Nov 20, 2008
Posts: 254
Rob has said it all. Just one minor point, if you create those empty HashSet just to create Cont1Data object, you may want to let Cont1Data to create them as well. So the clients of Cont1Data don't need to know how Cont1Data store the data.
Amandeep Singh
Ranch Hand

Joined: Jul 17, 2008
Posts: 836
So my final code is -




this looks good, before further to promote my changes into Production. Is there any other discrepancy ?
Duc Vo
Ranch Hand

Joined: Nov 20, 2008
Posts: 254
All your setSet methods should rename to addAllSet methods, since they don't adhere to the standard of Java bean contract, hence they will mislead other developers and even you after sometime. If you insist to have the setSet methods, then you should have both methods and they should look like below



Then your client code should use the second method if required to append to the existing set.
If you want to replace the existing set with a new set then the first method should be used.


Amandeep Singh
Ranch Hand

Joined: Jul 17, 2008
Posts: 836
when i need to add Strings to existing Set, then instead of making a String and make into Set then adding, i prefered this way of doing-


Duc Vo
Ranch Hand

Joined: Nov 20, 2008
Posts: 254
Perfect, now you got the hang of it
Amandeep Singh
Ranch Hand

Joined: Jul 17, 2008
Posts: 836
thank you for your help..
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: difference between changing the String after putting in Set or changing Set in Object
 
Similar Threads
HashSet and Strings doubt
Why doesn't Object type come out of a non-generic list?
equals & hashcode doubt
Ordering in HashSet
HashSet Duplicate element ?