动态数组:可调整大小的数组实现
增删慢:每次删除元素,都需要更改数组长度、拷贝以及移动元素位置。
查询快:由于数组在内存中是一块连续空间,因此可以根据地址+索引的方式快速获取对应位置上的元素。
一个类实现cloneable接口来指示object.clone()方法,该方法对于该类的实例进行字段的复制是合法的。在不实现cloneable接口的实例上调用对象的克隆方法会导致CloneNotSupportedException被抛出。
简言之:克隆就是依据已经有的数据,创造一份新的完全一样的数据拷贝
public class ArrayList_Clone {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add("人生就是旅途");
list.add("也许终点和起点会重合");
list.add("但是一开始就站在起点等待终点");
list.add("那么其中就没有美丽的沿途风景和令人难忘的过往");
//调用方法进行克隆
Object o = list.clone();
System.out.println(o == list);
System.out.println(o);
System.out.println(list);
}
}
public class ArrayList {
public Object clone() {
try {
ArrayList> v = (ArrayList>) super.clone();
v.elementData = Arrays.copyOf(elementData, size);
v.modCount = 0;
return v;
} catch (CloneNotSupportedException e) {
throw new InternalError(e);
}
}
}
案例:已知 A 对象的姓名为赵云,年龄30 。由于项目特殊要求需要将该对象的数据复制另外一个对象 B 中,并且此后 A 和 B 两个对象的数据不会相互影响 案例:已知 A 对象的姓名为关羽,年龄30,技能为大刀斩华雄(技能为一个引用数据类型 Skill ),由于项目 特殊要求需要将该对象的数据复制另外一个对象 B 中,并且此后 A 和 B 两个对象的数据不会相互影响
public class Student implements Cloneable{
//姓名
private String name;
//年龄
private Integer age;
public Student() {
}
public Student(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class Test01 {
public static void main(String[] args) throws CloneNotSupportedException {
//创建学生对象
Student stu1 = new Student("关羽", 29);
//再次创建一个新的学生对象
Student stu2 = new Student();
//把stu1对象name的值取出来赋值给stu2对象的name
stu2.setName(stu1.getName());
//把stu1对象age的值取出来赋值给stu2对象的age
stu2.setAge(stu1.getAge());
System.out.println(stu1 == stu2);
System.out.println(stu1);
System.out.println(stu2);
System.out.println("----此时不管修改哪个对象的内容,stu1和stu2都不会受到影响----");
stu1.setName("扈三娘");
System.out.println(stu1);
System.out.println(stu2);
}
}
//学生的技能类
public class Skill implements Cloneable{
private String skillName;
public Skill() {
}
public Skill(String skillName) {
this.skillName = skillName;
}
public String getSkillName() {
return skillName;
}
public void setSkillName(String skillName) {
this.skillName = skillName;
}
@Override
public String toString() {
return "Skill{" +
"skillName='" + skillName + '\'' +
'}';
}
}
public class Student implements Cloneable{
//姓名
private String name;
//年龄
private Integer age;
//技能
private Skill skill;
public Student() {
}
public Student(String name, Integer age, Skill skill) {
this.name = name;
this.age = age;
this.skill = skill;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Skill getSkill() {
return skill;
}
public void setSkill(Skill skill) {
this.skill = skill;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", skill=" + skill +
'}';
}
//浅克隆
@Override
public Student clone() throws CloneNotSupportedException {
return (Student) super.clone();
}
}
public class Test01 {
public static void main(String[] args) throws CloneNotSupportedException {
//用自定义对象演示 深浅拷贝
Skill skill = new Skill("大刀斩华雄");
Student s = new Student("关羽",31,skill);
//调用clone方法进行克隆
Student obj = s.clone();
//比较地址
System.out.println(s == obj);
System.out.println("被克隆对象: "+s);
System.out.println("克隆出来的对象: "+obj);
System.out.println("----华丽的分割线----");
//克隆之后,更改skill中的数据
skill.setSkillName("浑身是胆");
//更改克隆后对象的数据
obj.setName("赵云");
obj.setAge(19);
System.out.println("被克隆对象: "+s);
System.out.println("克隆出来的对象: "+obj);
}
}
/**
* @author itheima
* @since JDK 1.8
*/
public class Skill implements Cloneable{
private String skillName;
public Skill() {
}
public Skill(String skillName) {
this.skillName = skillName;
}
public String getSkillName() {
return skillName;
}
public void setSkillName(String skillName) {
this.skillName = skillName;
}
@Override
public String toString() {
return "Skill{" +
"skillName='" + skillName + '\'' +
'}';
}
//重写克隆方法,将权限修饰符改成public
@Override
public Skill clone() throws CloneNotSupportedException {
return (Skill) super.clone();
}
}
/**
* @author itheima
* @since JDK 1.8
*/
public class Student implements Cloneable{
//姓名
private String name;
//年龄
private Integer age;
//技能
private Skill skill;
public Student() {
}
public Student(String name, Integer age, Skill skill) {
this.name = name;
this.age = age;
this.skill = skill;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Skill getSkill() {
return skill;
}
public void setSkill(Skill skill) {
this.skill = skill;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", skill=" + skill +
'}';
}
//深克隆
@Override
public Student clone() throws CloneNotSupportedException {
//调用超类Object中方法clone进行对象克隆,得到一个新的学生对象
Student newStu = (Student) super.clone();
//调用学生类其属性skill的clone方法,对属性进行克隆
Skill s = this.skill.clone();
//再将克隆的Skill设置给克隆出来的学生对象
newStu.setSkill(s);
//返回克隆出来的学生对象
return newStu;
}
}
public class Test01 {
public static void main(String[] args) throws CloneNotSupportedException {
//用自定义对象演示 深浅拷贝
Skill skill = new Skill("倒拔垂杨柳");
Student s = new Student("鲁智深", 31, skill);
//调用clone方法进行克隆
Student obj = s.clone();
//比较地址
System.out.println(s == obj);
System.out.println("被克隆对象: " + s);
System.out.println("克隆出来的对象: " + obj);
System.out.println("----华丽的分割线----");
//克隆之后,更改skill中的数据
skill.setSkillName("荷花酒");
//更改克隆后对象的数据
obj.setName("扈三娘");
obj.setAge(19);
System.out.println("被克隆对象: " + s);
System.out.println("克隆出来的对象: " + obj);
}
}