一.比较器Comparable和Comparator
上一篇博客介绍了工具类Arrays工具类。我们可以对基本类型的数组调用Arrays.sort()函数来进行数组的排序。排序操作在日常开发中经常要使用到。那么String类和自定义类能不能使用Arrays.sort()来进行排序呢。下面我们来试试,如下:
public class Mystring {
<br style="word-wrap:break-word">
public static void main(String[] args) { <br style="word-wrap:break-word">
<br style="word-wrap:break-word">
String []a={"早上","中午","下午","傍晚","晚上"}; <br style="word-wrap:break-word">
<br style="word-wrap:break-word">
Person[] b={ new Person("小白",15),new Person("小黑",19), <br style="word-wrap:break-word">
new Person("小红",14),new Person("小紫",20)}; <br style="word-wrap:break-word">
Arrays.sort(a); <br style="word-wrap:break-word">
for(int i=0;i<a.length;i++) <br style="word-wrap:break-word">
System.out.print(a[i]); <br style="word-wrap:break-word">
System.out.print("rn"); <br style="word-wrap:break-word">
<br style="word-wrap:break-word">
Arrays.sort(b); <br style="word-wrap:break-word">
for(int i=0;i<b.length;i++) <br style="word-wrap:break-word">
System.out.println(b[i]); <br style="word-wrap:break-word">
} <br style="word-wrap:break-word">
<br style="word-wrap:break-word">
}
//自定义类
class Person {
<br style="word-wrap:break-word">
public String name; <br style="word-wrap:break-word">
<br style="word-wrap:break-word">
public int age; <br style="word-wrap:break-word">
public Person(String name,int age) { <br style="word-wrap:break-word">
this.name=name; <br style="word-wrap:break-word">
this.age=age; <br style="word-wrap:break-word">
<br style="word-wrap:break-word">
} <br style="word-wrap:break-word">
}
复制代码
程序运行结果:
我们发现String可以调用Arrays.sort()函数,而我们自定义的Person类报错,看错误的关键字 Comparable
打开String源码
由此引入比较器Comparable,我们下面利用Comparable接口来实现Person使用Arrays.sort()按年龄排序递增排序。
Comparable接口能够对实现它的类的对象进行排序,主要使用compareTo函数来实现排序。compareTo函数返回int类型,分别返回-1,0,1对应小于,等于,大于。
把代码改为:
public class Mystring {
<br style="word-wrap:break-word">
public static void main(String[] args) { <br style="word-wrap:break-word">
<br style="word-wrap:break-word">
String []a={"早上","中午","下午","傍晚","晚上"}; <br style="word-wrap:break-word">
<br style="word-wrap:break-word">
Person[] b={ new Person("小白",15),new Person("小黑",19), <br style="word-wrap:break-word">
new Person("小红",14),new Person("小紫",20)}; <br style="word-wrap:break-word">
Arrays.sort(a); <br style="word-wrap:break-word">
for(int i=0;i<a.length;i++) <br style="word-wrap:break-word">
System.out.print(a[i]); <br style="word-wrap:break-word">
System.out.print("rn"); <br style="word-wrap:break-word">
<br style="word-wrap:break-word">
Arrays.sort(b); <br style="word-wrap:break-word">
for(int i=0;i<b.length;i++) <br style="word-wrap:break-word">
System.out.println(b[i]); <br style="word-wrap:break-word">
} <br style="word-wrap:break-word">
<br style="word-wrap:break-word">
}
//自定义类
class Person implements Comparable<Person>{
<br style="word-wrap:break-word">
public String name; <br style="word-wrap:break-word">
<br style="word-wrap:break-word">
public int age; <br style="word-wrap:break-word">
public Person(String name,int age) { <br style="word-wrap:break-word">
this.name=name; <br style="word-wrap:break-word">
this.age=age; <br style="word-wrap:break-word">
<br style="word-wrap:break-word">
} <br style="word-wrap:break-word">
//比较器的比较函数 <br style="word-wrap:break-word">
/** <br style="word-wrap:break-word">
* 如果当前对象小于比较对象,返回-1 <br style="word-wrap:break-word">
* 如果当前对象等于比较对象,返回0 <br style="word-wrap:break-word">
* 如果当前对象大于比较对象,返回1 <br style="word-wrap:break-word">
*/ <br style="word-wrap:break-word">
@Override <br style="word-wrap:break-word">
public int compareTo(Person o) { <br style="word-wrap:break-word">
//对象为空,抛出空指针异常 <br style="word-wrap:break-word">
if(o==null) <br style="word-wrap:break-word">
throw new NullPointerException(); <br style="word-wrap:break-word">
if(this.age<o.age) <br style="word-wrap:break-word">
return -1; <br style="word-wrap:break-word">
if(this.age>o.age) <br style="word-wrap:break-word">
return 1; <br style="word-wrap:break-word">
return 0; <br style="word-wrap:break-word">
} <br style="word-wrap:break-word">
//重写toString方法 <br style="word-wrap:break-word">
@Override <br style="word-wrap:break-word">
public String toString() { <br style="word-wrap:break-word">
return "Person [name=" + name + ", age=" + age + "]"; <br style="word-wrap:break-word">
} <br style="word-wrap:break-word">
}
复制代码
为自定义的Person实现比较器Comparable接口,即可调用Arrays.sort()进行排序。
另外还有另一种实现方法,实现Comparator接口。
public class Mystring {
<br style="word-wrap:break-word">
public static void main(String[] args) { <br style="word-wrap:break-word">
<br style="word-wrap:break-word">
String []a={"早上","中午","下午","傍晚","晚上"}; <br style="word-wrap:break-word">
<br style="word-wrap:break-word">
Person[] b={ new Person("小白",15),new Person("小黑",19), <br style="word-wrap:break-word">
new Person("小红",14),new Person("小紫",20)}; <br style="word-wrap:break-word">
Arrays.sort(a); <br style="word-wrap:break-word">
for(int i=0;i<a.length;i++) <br style="word-wrap:break-word">
System.out.print(a[i]); <br style="word-wrap:break-word">
System.out.print("rn"); <br style="word-wrap:break-word">
<br style="word-wrap:break-word">
Arrays.sort(b,new PersonComparator()); <br style="word-wrap:break-word">
for(int i=0;i<b.length;i++) <br style="word-wrap:break-word">
System.out.println(b[i]); <br style="word-wrap:break-word">
} <br style="word-wrap:break-word">
<br style="word-wrap:break-word">
}
//自定义类
class Person {
public String name; <br style="word-wrap:break-word">
<br style="word-wrap:break-word">
public int age; <br style="word-wrap:break-word">
public Person(String name,int age) { <br style="word-wrap:break-word">
this.name=name; <br style="word-wrap:break-word">
this.age=age; <br style="word-wrap:break-word">
<br style="word-wrap:break-word">
} <br style="word-wrap:break-word">
@Override <br style="word-wrap:break-word">
public String toString() { <br style="word-wrap:break-word">
return "Person [name=" + name + ", age=" + age + "]"; <br style="word-wrap:break-word">
} <br style="word-wrap:break-word">
}
class PersonComparator implements Comparator<Person>{
//比较器的比较函数 <br style="word-wrap:break-word">
/** <br style="word-wrap:break-word">
* 如果当前对象小于比较对象,返回-1 <br style="word-wrap:break-word">
* 如果当前对象等于比较对象,返回0 <br style="word-wrap:break-word">
* 如果当前对象大于比较对象,返回1 <br style="word-wrap:break-word">
*/ <br style="word-wrap:break-word">
@Override <br style="word-wrap:break-word">
public int compare(Person o1, Person o2) { <br style="word-wrap:break-word">
//对象为空,抛出空指针异常 <br style="word-wrap:break-word">
if(o1==null||o2==null) <br style="word-wrap:break-word">
throw new NullPointerException(); <br style="word-wrap:break-word">
if(o1.age<o2.age) <br style="word-wrap:break-word">
return -1; <br style="word-wrap:break-word">
if(o1.age>o2.age) <br style="word-wrap:break-word">
return 1; <br style="word-wrap:break-word">
return 0; <br style="word-wrap:break-word">
} <br style="word-wrap:break-word">
<br style="word-wrap:break-word">
}
复制代码
二.对象的克隆Clone
将一个对象复制一份,称作对象的克隆技术。克隆对象分为两步。
1.实现Cloneable标记接口
Cloneable是一个标记接口,此接口没有定义任何方法。只是作为一个标记给虚拟机。
2.重写Object的clone方法
//自定义类person实现Cloneable接口
class Person implements Cloneable {
public String name; <br style="word-wrap:break-word">
<br style="word-wrap:break-word">
public int age; <br style="word-wrap:break-word">
public Person(String name,int age) { <br style="word-wrap:break-word">
this.name=name; <br style="word-wrap:break-word">
this.age=age; <br style="word-wrap:break-word">
<br style="word-wrap:break-word">
} <br style="word-wrap:break-word">
//重写Object的clone方法 <br style="word-wrap:break-word">
@Override <br style="word-wrap:break-word">
protected Object clone() throws CloneNotSupportedException <br style="word-wrap:break-word">
{ <br style="word-wrap:break-word">
return super.clone(); <br style="word-wrap:break-word">
} <br style="word-wrap:break-word">
}
复制代码
克隆的调用:
public static void main(String[] args) {
<br style="word-wrap:break-word">
Person temp=new Person("王尼玛",18); <br style="word-wrap:break-word">
<br style="word-wrap:break-word">
try { <br style="word-wrap:break-word">
Person ok=(Person)temp.clone();//把Object类转化为Person、 <br style="word-wrap:break-word">
System.out.println(ok.name);//输出王尼玛 <br style="word-wrap:break-word">
} catch (CloneNotSupportedException e) { <br style="word-wrap:break-word">
e.printStackTrace(); <br style="word-wrap:break-word">
} <br style="word-wrap:break-word">
<br style="word-wrap:break-word">
}
复制代码
这样既可以完成对一个对象的克隆,当我们要创建一系列类似的对象时,可以考虑使用克隆技术可以得到更好的性能,比你new创建好一些