Cloneable、Comparable、Comparator的应用

来源:互联网 发布:网络切换器 编辑:程序博客网 时间:2024/05/16 10:19

CloneCompareTest.java

 

/*
 * 程序演示如下功能:
 * 1、对象克隆
 *   浅克隆:类中如果没有引用类型的变量,可用浅克隆。这时,在覆写的clone()方法中,只需调用Object的clone()并返回即可。
 *   深克隆:类中有引用类型,在覆写的clone()方法中如果只调用Object的clone(),只能实现浅克隆。也就是改变对象或克隆对象所包含的引用类型变量的值,会在对象和克隆对象中同时反映。所以要实现深克隆,就要在覆写的clone()方法中,除了调用Object的clone()方法外,还要调用引用类型变量的clone()方法(当然,前提是它也实现了Cloneable接口,并覆写了clone())。
 *   对象克隆的条件:
 *    A.实现Cloneable接口(它其实是一个标识接口)
 *    B.覆写clone()方法,并把访问权根由protected改为public
 * 2、Comparable和Comparator的应用和区别
 *   A.一个类实现了Camparable接口,则表明这个类的对象之间是可以相互比较的(即像数字一样有自然顺序),这个类对象组成的集合就可以直接使用sort方法排序。
 *   B.Comparator可以看成一种算法的实现,将算法和数据分离,可以在下面两种环境下使用:
 *   a)类的设计师没有考虑到比较问题而没有实现Comparable,可以通过Comparator来实现排序而不必改变对象本身
 *   b)可以使用多种排序标准,比如升序、降序等
 */


package com.lwj.test;

import java.util.Arrays;

public class CloneCompareTest {
 public static void main(String[] args) throws CloneNotSupportedException  {
  // TODO Auto-generated method stub
  Publish pub1=new Publish("小陆工作室");
  Book book1=new Book("Java日记","陆武军",26.6,pub1);
  Book book2=(Book)book1.clone();
  book2.getPub().setName("老陆工作室");//这里改变book2的出版社pub的值,看看book1的pub改变吗?
  System.out.println("————————原来的对象————————");
  System.out.println(book1);
  System.out.println("————————克隆的对象————————");
  System.out.println(book2);
  
  Publish pub2=new Publish("先锋出版社");
  Book book3=new Book("C#技术内幕","小泽",65.3,pub2);
  Book[] books={book1,book2,book3};
  System.out.println("————————用books实现的Comparable完成按价格排序功能————————");
  Arrays.sort(books);//用books实现的Comparable完成排序功能,这叫自然顺序
  print(books);
  System.out.println("————————用Comparator实现按价格price与自然顺序逆序功能————————");
  Arrays.sort(books,new BookComparator());//用Comparator实现排序功能,这里实现的是按价格price与自然顺序逆序
  print(books);
 }
 
 public static void print(Book[] books){
  for(Book book:books)
   System.out.println(book);
 }
}
 

Publish.java

 

package com.lwj.test;

/*
 * Publish实现了对象克隆和自然排序的功能
 */
class Publish implements Cloneable,Comparable<Publish>{
 private String name;

 public Publish() {
 }

 public Publish(String name) {
  this.name = name;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 @Override
 public  Object clone() throws CloneNotSupportedException {
  // TODO Auto-generated method stub
  return super.clone();//调用super.clone()即Object 的clone()方法能识别出你要复制的是哪一个对象,然后为此对象分配空间,并进行对象的复制,将原始对象的内容一一复制到新的对象空间去。

 }
 
 @Override
 public int compareTo(Publish o) {
  // TODO Auto-generated method stub
  return this.name.compareTo(o.getName());//用出版社的名字name实现自然排序。我理解,Comparable就是属于对象的自然属性,所以可以对象的类中实现。与Comparator不同的是,Comparator就可以理解为附加在对象上的操作,这在调用Arrays.sort()方法时可以看出不同。
 }

 public String toString(){
  return "出版社:"+this.name;
 }
}

 

 

PublishComparator.java

 

package com.lwj.test;

import java.util.Comparator;

//为什么要单独写一个类实现Comparator呢?这就是算法和数据的分离!!!也符合Comparator接口设计的初衷。
class PublishComparator implements Comparator<Publish> {
 @Override
 public int compare(Publish o1, Publish o2) {
  // TODO Auto-generated method stub
  return o1.compareTo(o2);//调用Publish对象的自然顺序为序
 }
}
 

Book.java

 

package com.lwj.test;

//Book实现了对象克隆和自然排序的功能
class Book implements Cloneable,Comparable<Book> {
 private String name;
 private String author;
 private double price;
 private Publish pub;
 
 public Book() {
 }
 
 public Book(String name, String author, double price, Publish pub) {
  this.name = name;
  this.author = author;
  this.price = price;
  this.pub = pub;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public String getAuthor() {
  return author;
 }
 public void setAuthor(String author) {
  this.author = author;
 }
 public double getPrice() {
  return price;
 }
 public void setPrice(double price) {
  this.price = price;
 }
 public Publish getPub() {
  return pub;
 }
 public void setPub(Publish pub) {
  this.pub = pub;
 }
 @Override
 public Object clone() throws CloneNotSupportedException {
  // TODO Auto-generated method stub
  Book book;
  book=(Book)super.clone();
  book.pub=(Publish)pub.clone();//这里将pub的对象也克隆,实现了深克隆。若没有这句,只实现浅克隆。
  return book;
 }
 @Override
 public int compareTo(Book o) {
  // TODO Auto-generated method stub
  return Double.compare(this.price, o.getPrice());//用price实现自然顺序。另外,这里的o.getPrice()也可用o.price代替,想想为什么?
 }

 public String toString(){
  return "书名:"+this.name+"/t"+"作者:"+this.author+"/t"+"价格:"+this.price+"/t"+this.pub.toString();
 }
}

 

BookComparator.java

 

package com.lwj.test;

import java.util.Comparator;

class BookComparator implements Comparator<Book> {

 @Override
 public int compare(Book o1, Book o2) {
  // TODO Auto-generated method stub
  return Double.compare(o2.getPrice(), o1.getPrice());//这里实现了逆序,与Book对象的自然顺序不同。如果return Double.compare(o1.getPrice()-o2.getPrice());就是自然顺序
 }

}

 

运行结果为:

————————原来的对象————————
书名:Java日记 作者:陆武军 价格:26.6 出版社:小陆工作室
————————克隆的对象————————
书名:Java日记 作者:陆武军 价格:26.6 出版社:老陆工作室
————————用books实现的Comparable完成按价格排序功能————————
书名:Java日记 作者:陆武军 价格:26.6 出版社:小陆工作室
书名:Java日记 作者:陆武军 价格:26.6 出版社:老陆工作室
书名:C#技术内幕 作者:小泽 价格:65.3 出版社:先锋出版社
————————用Comparator实现按价格price与自然顺序逆序功能————————
书名:C#技术内幕 作者:小泽 价格:65.3 出版社:先锋出版社
书名:Java日记 作者:陆武军 价格:26.6 出版社:小陆工作室
书名:Java日记 作者:陆武军 价格:26.6 出版社:老陆工作室