-ArrayList is Cloneable (same for Set and Map), but List is not Cloneable.
-I want to clone what was passed as a List instead of an ArrayList, but there are situations where I can't do it obediently. What should i do?
-The sample is shown below, but there is a method to get the clone method of the actual object class and invoke it.
・ This is where I feel frustrated when using Java. It is the same regret that int ⇔ Integer can be assigned but int [] ⇔ Integer [] cannot be assigned.
-For example, if you do a keySet with HashSet, HashMap $ KeySet will be returned, but this is not Cloneable and cannot be cloned by the method shown in the sample. This kind of thing is a problem ....
・ Another snake leg. The sample uses getDeclaredMethod. -GetDeclaredMethod (getDeclaredMethods) gets the methods declared in the class. -GetMethod (getMethods) including the methods declared in the base class.
★ Addition ★ As pointed out by felis below, you can use CopyOf of List from Java 10. The test program below is running on JDK 1.6.
package jp.avaj.lib.algo;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import jp.avaj.lib.test.ArTest;
import jp.avaj.lib.test.L;
/**
Clone List
ArrayList is cloneable, but List is not cloneable.Same for Set and Map.
*/
public class Tips0056 {
public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
List<String> list = ArList.construct("a,b,c");
List<String> newList;
//This is a compile error
//newList = (List<String>)list.clone();
L.p("You can do this"); //However, it is unknown whether it is an ArrayList when passed as a List..
newList = (List<String>)((ArrayList)list).clone();
L.p(newList.toString());
L.p("Get the clone method from the actual class and invoke it");
//Get the clone method in the actual class.If there is a parameter, specify it at the end, but it is unnecessary now
Method cloneMethod = list.getClass().getDeclaredMethod("clone");
//If there is no method, an exception will be thrown, so if you come here, there is a method.
//Execute the method.If there is a parameter, specify it at the end, but it is unnecessary now.
newList = (List<String>)cloneMethod.invoke(list);
//Check the result.
ArTest.equals("clone","expected",3,"size",newList.size());
ArTest.equals("clone","expected","a","(0)",newList.get(0));
ArTest.equals("clone","expected","b","(1)",newList.get(1));
ArTest.equals("clone","expected","c","(2)",newList.get(2));
//Check visually
L.p(newList.toString());
}
}
The result is as follows
You can do this
[a, b, c]
Get the clone method from the actual class and invoke it
OK clone:expected=3:size=3
OK clone:expected=a:(0)=a
OK clone:expected=b:(1)=b
OK clone:expected=c:(2)=c
[a, b, c]
Recommended Posts