What is the best tool for java's clone() method generation in Eclipse Galileo available from repositories?
What is the reason, that prevents Eclipse developers from including this tool in standard release?
It's very hard to implement clone() right. It is considered not a good practice to do so. Bloch (Effective Java) suggest that using clone() should be avoided. Use other means of shallow cloning, like copy-constructors or utilities like commons-beanutils.
I absolutely agree with Bozho. However, if there is a need for it and you have large number of member fields to copy over and you need to quick way to list them out then you could make use of the "toString" generator to get a code template.
In the generate toString option use the Code style : "StringBuilder/StringBuffer" which would list all member fields and append to the StringBuilder. Then you could change the appends to appropriate setters of the cloned object.
Related
I need to deep clone a object which has some non-serialization objects as members in Java.
Can you provide some reference what can i use for this ?
Note:
Please provide reference to some standard library of java. I don't want to use any unapproved/private package or library.
Or some code pointers how can i clone the object ?
In the absence of standardisation of values in Java, I strongly suggest avoiding any dodgy reflection/code generation scheme.
If you can, changing to immutable types removes the need to copy.
Other than that, just write the code neatly. If there are a lot of collections, writing map methods will help to avoid the palaver of Streams (and be faster).
I am trying spark with java and I get stuck by the immutable collections in java.
As I understand in Scala when two immutable lists are combined, no deep copy happens. However the available immutable list in java, like guava, does the defensive copy. (correct me if I am wrong)
So simply my questions are:
Is there some Java immutable list which has the same behavior as
scala immutable list ?
If the answer of the first question is NO, what's the
general(standard) way to use scala immutable collection in java code
?
Thanks very much.
Scala Lists is a so-called persistent collection with the persistent referring to the fact, that no defensive copying happens. If you google for Java persistent collection you should find several links to get you started. In addition to that, there are a number of libraries that aim to bring the essence of functional programming to Java. As persistent collections are inherently functional, those frameworks often include their own collections implementation. The two libraries I've worked with and can recommend are Javaslang and Functional Java but there are more out there than these two (e.g. pccollections, jOOλ, …).
As for using Scala collections from Java, I've always found this to be somewhat awkward. I would suggest to write a Scala class/object, that gives you easy (as from-Java-easy) access to the scala.collection.JavaConverters, so that you can expose your scala.collection.immutable.List as a java.util.List and work with that interface.
Given an object we will call loc that simply holds 2 int member values, I believe I need to come up with a mechanism to generate a hashcode for the object. What I tried below doesn't work as it uses an object reference, and the 2 references will be different despite having the same members variables.
Map<Loc,String> mapTest = new HashMap<Loc,String>();
mapTest.put(new Loc(1,2), "String 1");
mapTest.put(new Loc(0,1), "String 2");
mapTest.put(new Loc(2,2), "String 3");
System.out.println("Should be String 2 " + mapTest.get(new Loc(0,1)));
After some reading it seems I need to roll my own hashcode for this object, and use that hashcode as the key. Just wanted to confirm that I am on the right track here, and if someone could guide me to simple implementations to look at that would be excellent.
Thanks
Yes, you need to override equals() and hashCode() and they need to behave consistently (that is, equal objects have to have the same hash code). No you do not use the hash coe directly; Map uses it.
Yes, you're on the right track.
See articles like this for more details.
There are a lot of different ways to implement a hashcode, you'll probably just want to combine the hashcodes of each integer primitive.
Writing correct equals and hashcode methods can be tricky and the consequences of getting it wrong can be subtle and annoying. If you are able to, I would use the apache commons-lang library and take advantage of the HashCodeBuilder and EqualsBuilder classes. They will make it much easier to get the implementations right. The benefit of using these libraries is that it is much harder to get the boiler plate wrong, they hide the visual noise these methods tend to create and they make it harder for someone to come a long later and mess it up. Of course another alternative is to let your IDE generate those methods for you which works but just creates more of the noisy code vomit Java is known for.
If you want to use your type as a key type in a map, it's essential that it provides sane implementations of equals and hashCode. Fortunately, you don't have to write these implementations manually. Eclipse (and I guess other IDEs as well) can generate this boilerplate for you. Or you can even use Project Lombok for that.
Ideally the object to be used as a key in a map should be immutable. This can save you from many bugs led to by the equality issues in the context of mutation.
You need to implement both hashCode() and equals(). Joshua Bloch's Effective Java should be the definitive source on the "how" part of your question, and I'm not sure if it's okay to reproduce it here, so I'll just refer you to it.
I have a medium-sized Java project in Eclipse, which uses Vector<E> instead of the preferred ArrayList<E>. I would like to replace those.
Is there any way, using Eclipse, to change all these? Any refactoring method?
Or would it be sufficient to do a general search-and-replace for every Vector<String> occurrence? Are there any caveats to this? What are situations in which this approach would fail?
Actually, I just did the latter, and it worked for my application, but this should be a more general question.
Vector was retrofitted to implement List in Java 1.2 when the Collections API, which includes ArrayList, was introduced. So it has both old-style methods like elementAt(), and new-style methods like get(), which are largely work-alike.
The old methods aren't in List or ArrayList, so if you searched and replaced, and were using old methods, it would fail to compile. Easy enough to find and fix those, though. Same for iterator()/Iterator replacing Enumeration and such.
Vector's operations were synchronized; if the program relied on that for correctness, it could fail if replaced with ArrayList, which is not. Wrap with Collections.synchronizedList() if you need the old behavior. This is a source of subtler bugs.
The only things that could make it go wrong are
if you use methods that are in Vector, but not in ArrayList (but I'm not even sure such a method exists)
if you're relying on the synchronized-ness of Vector in some of your classes to make them thread-safe.
if you use reflection somewhere and this reflection-based code uses the Vector class name.
if you use some legacy API still using Vector and not List of ArrayList (like some Swing classes)
A number of times I've argued that using clone() isn't such a bad practice. Yes, I know the arguments. Bloch said it's bad. He indeed did, but he said that implementing clone() is bad. Using clone on the other hand, especially if it is implemented correctly by a trusted library, such as the JDK, is OK.
Just yesterday I had a discussion about an answer of mine that merely suggests that using clone() for ArrayList is OK (and got no upvotes for that reason, I guess).
If we look at the #author of ArrayList, we can see a familiar name - Josh Bloch. So clone() on ArrayList (and other collections) is perfectly fine (just look at their implementations).
Same goes for Calendar and perhaps most of the java.lang and java.util classes.
So, give me a reason why not to use clone() with JDK classes?
So, give me a reason why not to use clone() with JDK classes?
Given an ArrayList reference, you would need a getClass check to check that it is not a subclass of the JDK class. And then what? Potential subclasses cannot be trusted. Presumably a subclass would have different behaviour in some way.
It requires that the reference is more specific than List. Some people don't mind that, but the majority opinion is that that is a bad idea.
You'll have to deal with a cast, an unsafe cast at that.
From my experience, the problem of clone() arises on derived classes.
Say, ArrayList implements clone(), which returns an object of ArrayList.
Assume ArrayList has an derived class, namely, MyArrayList. It will be a disaster if MyArrayList does not override the clone() method. (By default it inherits the code from ArrayList).
The user of MyArrayList may expect clone() to return an object of MyArrayList; however, this is not true.
This is annoying: if a base class implements clone(), its derived class has to override the clone() all the way.
I will answer with a quote from the man himself (Josh Bloch on Design - Copy Constructor versus Cloning):
There are very few things for which I use Cloneable anymore. I often provide a public clone method on concrete classes because people expect it.
It can't be any more explicit than this: clone() on his Collection Framework classes are provided because people expect it. If people stop expecting it, he would've gladly thrown it away. One way to get people to stop expecting it is to educate people to stop using it, and not to advocate its use.
Of course, Bloch himself also said (not exact quote but close) "API is like sex: make one mistake and you support it for life". Any public clone() can probably never be taken back. Nevertheless, that's not a good enough reason to use it.
In order not to encourage other, less experienced, developers to implement Clone() themselves. I've worked with many developers whose coding styles are largely copied from (sometimes awful) code that they've worked with.
It does not enforce whether the implementer will do a deep or shallow copy.
Using clone can be risky very risky if you don't check the implementation of this clone method... as you can suppose a clone impl can act in different ways... shallow or deep clone... and some developpers may not always check what kind of clone they will retrieve...
In a big application, big team, it's also risky because when cloning is used, if you modify the clone implementation you may modify the application behaviour and create new bugs... and have to check everywhere the clone was called (but it can be the same for other object methods like equals, toString...
When modifying the clone of a small subclass A (from Deep to Shallow clone for exemple), if an instance of B has a reference to A and a deep clone impl, then since the objects referenced in A are not shallow cloned, the B clone won't be a deep clone anymore (and it's the same for any class referencing a B instance...).
It's not easy to deal with the deepness of your clone methods.
Also when you have an interface (extending Clonable) and many (many!) implementations, sometimes you will check some impl and see that clones are deep, and call a clone on the inteface but you can't be sure at runtime all impl really have deep clone and can introduce bugs...
Think it could be better to impl for each method a shallowClone and a deepClone method, and on very specific needs implement customised methods (for exemple you want a clone and limit the depth of this clone to 2, make a custom impl for that in all classes concerned).
Don't think it's a big matter to use a clone method on a JDK class since it's not going to be changed by another developper, or at least not often. But you'd better not call clone on JDK classes if you don't know the class implementation at compile time. I mean calling the clone on an ArrayList is not a matter but calling it on a Collection could be dangerous since another Collection implementation could be introduced by another developper (he can even extends a Collection impl) and nothing tells you that the clone of this impl will work like you expect it to do...
If the types in your collection are mutable, you have to worry about whether just the collection, itself, will be cloned, or whether the elements will also be cloned... hence implementing your own function, where you know whether the elements or just the container will be cloned will make things much clearer.