JAVA中的常用类
比较器
在Java中经常会涉及到对象数组的排序问题,那么就涉及到对象之间的比较问题。
通常对象之间的比较可以从两个方面去看:
第一个方面:对象的地址是否一样,也就是是否引用自同一个对象。这种方式可以直接使用“==“来完成。
第二个方面:以对象的某一个属性的角度去比较。
对于JDK8而言,有三种实现对象比较的方法:
1、覆写Object类的equals()方法;
2、继承Comparable接口,并实现compareTo()方法;
3、定义一个单独的对象比较器,继承自Comparator接口,实现compare()方法。
由于使用的排序方式的不同,具体选择哪种方法来实现对象的比较也会有所不同。
第一种方法比较便于理解,复写equals()方法一般用于自己实现的对象数组排序,而对于在应用Java内置的排序算法时,使用后两种方式都是可以实现的。
第二种方式,这种方式就是让自己编写的类继承Comparable接口,并实现接口的compareTo()方法,也叫做内部比较器
import java.util.Arrays;
public static void main(String[] args) {
Person [] arr = new Person [5];
arr[0] = new Person("zhangsan",28);
arr[1] = new Person("lisi",20);
arr[2] = new Person("wangwu",33);
Arrays.sort(arr);
for(Person p : arr){
System.out.println("===name : "+p.getName() + "== age: "+p.getAge());
}
}
public class Person implements Comparable<Person> {
private String name = "";
private int age = 0;
private int[] arr = null;
public Person(String name, int age, int[] arr) {
//拿取下面的name,age
this(name, age);
this.arr = arr;
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// 内部比较器
@Override
public int compareTo(Person p) {
if(getAge()>p.getAge()){
return 1;
}else if(getAge()<p.getAge()){
return -1 ;
}else{
return 0;
}
}
}
结果为这样
===name : lisi== age: 20
===name : zhangsan== age: 28
===name : wangwu== age: 33
从JDK1.8开始出现了Comparator接口,它的出现解决了当需要在已经开发好的代码基础上完善对象的比较功能时不想更改之前的代码的问题。这种情况,我们需要单独定义一个对象比较器,继承Comparator接口。具体实现代码如下:
public class MyPersonCompare implements Comparator<Person>{
@Override
public int compare(Person p1, Person p2) {
if(p1.getName().compareTo(p2.getName()) == 0 ){
if(p1.getAge() > p2.getAge()){
return -1 ;
}else if(p1.getAge() < p2.getAge()){
return 1 ;
}else{
return 0;
}
}else {
return p1.getName().compareTo(p2.getName()) ;
}
}
}
Arrays.sort(arr,new MyPersonCompare());
for(Person p : arr){
System.out.println("===name : "+p.getName() + "== age: "+p.getAge());
}
结果为这样
===name : lisi== age: 20
===name : wangwu== age: 33
===name : zhangsan== age: 28
toString()方法
第一种简单的方式
String s = "hello " ;
System.out.println(s.toString());
打印出:hello
其次
Person p = new Person("zhangsan",12, new int [] {1,2,3});
System.out.println(p.toString());
打印出:com.jj.s.Person@15db9742
因为在Object中它已经写好了方法
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
那么此时我们应该去重写toString方法
此时只需要鼠标右键子类方法
Source-->Generate toString
把需要重写的字段勾上就完事了
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", arr=" + Arrays.toString(arr) + "]";
}
clone()
创建并返回此对象的一个副本。
clone是保护的,只能在子类中访问。要克隆的对象必须实现Cloneable接口。
如果在mian方法使用,需要将protected改为public
代码如下
public static void main(String[] args) throws CloneNotSupportedException {
Person p = new Person("zhangsan",12, new int [] {1,2,3});
Person p1 = (Person) p.clone();
System.out.println(p.toString());
System.out.println(p1.toString());
结果:Person [name=zhangsan, age=12, arr=[1, 2, 3]]
Person [name=zhangsan, age=12, arr=[1, 2, 3]]
}
要是你生成了奇怪的符号,那么请看toString()
public class Person implements Cloneable{
@Override-->表示重写
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
equals(Object obj)
此时只说明一种用法
//这个相等默认为 t1==t2,默认判断作用域是否相等
Test t1=new Test();
Test t2=new Test();
Test t3=t2;
System.out.println(p1.equals(p2));
System.out.println(p3 == p2);//判断是否是同一个对象,在内存中的地址是否相等。
System.out.println(p3.equals(p2)); // 判断2个对象是否相等,默认的相等规则是“==”
结果:
false
true
true
Person p1 = new Person("zhangsan",12);
Person p2 = new Person("zhangsan",12);
Person p3 = p2 ;
System.out.println(p1.equals(p2));
结果为:false
public static void main(String[] args) throws CloneNotSupportedException {
Test a=new Test("zz",1);
Test c=new Test("zz",2);
System.out.println(a.equals(c));
}
public class Test {
@Override
public boolean equals(Object obj) {
if (this.name == null && this.age == 0) {
return false;
} else if (obj instanceof Test) {
Test tt = (Test) obj;
if (this.name.equals(tt.name)&&tt.age==this.age) {
return true;
}
}
return false;
}
}
结果为:false