在java中经常会涉及到对对象数组的排序问题,那么就涉及到对象之间的比较问题,
但是在java的对象中正常情况下只能使用 ==, != 不可使用 >, < 来比较两个对象的大小, 但是在开发中要比较对象的大小时,比较器就顺势而生了
在java中我们常用的比较器有:
自然排序: Comparable
定制排序: Comparator
自然排序: Comparable
Comparable接口强行对实现它的每个类的对象进行整体排序。这种排序被称 为类的自然排序。
实现Comparable类必须实现它的compareTo(Object obj)方法 ,也就是比较的内容要放在compareTo(Object obj)方法中实现
Comparable 的典型实现:(默认都是从小到大排列的)
String:按照字符串中字符的Unicode值进行比较
Character:按照字符的Unicode值来进行比较
数值类型对应的包装类以及BigInteger、BigDecimal:按照它们对应的数值 大小进行比较
Boolean:true 对应的包装类实例大于 false 对应的包装类实例 Date、Time等:后面的日期时间比前面的日期时间大
实现compareTo(Object obj)的结果
重写compareTo()的规则:
如果当前对象this大于形参对象obj,则返回正整数
如果当前对象this小于形参对象obj,则返回负整数
如果当前对象this等于形参对象obj,则返回0
packageCompare;importjava.util.Arrays;public classComparableTestTwo {public static voidmain(String[] args) {
GoodsTestTwo [] arr= new GoodsTestTwo[3];
arr[0] = new GoodsTestTwo("老王",123);
arr[1] = new GoodsTestTwo("老张",121);
arr[2] = new GoodsTestTwo("老刘",110);
Arrays.sort(arr);//先排序
System.out.println(Arrays.toString(arr)); //再求值 [GoodsTestTwo{name='老刘', price=110.0}, GoodsTestTwo{name='老张', price=121.0}, GoodsTestTwo{name='老王', price=123.0}]
}
}class GoodsTestTwo implementsComparable{
@Overridepublic int compareTo(Object o){ //实现Comparable 接口的compareTo()
if(o instanceof GoodsTestTwo){ //判断是否是同一种类型
GoodsTestTwo goodsO = (GoodsTestTwo) o; //进行类型转化//方式一
if(this.price >goodsO.price){return 1;
}else if(this.price
}else{ //相等
return 0;//return this.name.compareTo(goodsO.name);//如果相等就按照其名字排序
}//方式一结束, 方式二开始//return Double.compare(this.price,goodsO.price);//点开源码看到方式一就是其源码实现过程
// 想获得从大到小的值 就修改为return Double.compare(this.price,goodsO.price);
}throw new RuntimeException("输入的有误");
}privateString name;private doubleprice;publicString getName() {returnname;
}public voidsetName(String name) {this.name =name;
}public doublegetPrice() {returnprice;
}public void setPrice(doubleprice) {this.price =price;
}publicGoodsTestTwo(){};public GoodsTestTwo (String name, doubleprice){this.name =name;this.price =price;
}
@OverridepublicString toString() {return "GoodsTestTwo{" +
"name='" + name + '\'' +
", price=" + price +
'}';
}
}
上面的求值的时候如果想获取从大到小的值就改为:
想获得从大到小的值 就修改为 return Double.compare(this.price,goodsO.price);
定制排序 : Comparator
当元素的类型没有实现Comparable接口自然排序时 或者实现了Comparable自然排序但是排序规则不适应本身时 可以使用Comparator定制排序,
强行对多个对象进行整体排序
排序要求:
重写compare(Object obj, Object obj2) 比较obj1 和obj2的大小如果方法返回为正整数,则是obj1大如果方法返回为负整数 则是obj2大为0则是两者相同
重写Compare(Object obj1, Object obj2)方法比较obj1和obj2
如果返回正整数 则表示obj1 大于obj2
如果返回负整数则obj2 大于obj1
如果返回0两者相等
eg:
public classComparatorTestOne {public static voidmain(String[] args) {
String[] arr= new String[]{"AA", "CC", "KK", "MM", "GG", "JJ"};
Arrays.sort(arr,newComparator() {
@Overridepublic intcompare(Object o1, Object o2) {if (o1 instanceof String && o2 instanceofString) {
String str1=(String) o1;
String str2=(String) o2;return -str1.compareTo(str2);
}throw new RuntimeException("输入有误");
}
});
System.out.println(Arrays.toString(arr));//[MM, KK, JJ, GG, CC, AA]//==========
GoodsTest [] arry= new GoodsTest[5];
arry[0] = new GoodsTest("laowang",123);
arry[1] = new GoodsTest("laozhang",103);
arry[2] = new GoodsTest("laoli",100);
arry[3] = new GoodsTest("laoliu",113);
arry[4] = new GoodsTest("laohong",78);//先安装名字从低到高 再按照价格 从高到底
Arrays.sort(arry, newComparator(){
@Overridepublic intcompare(Object obj1, Object obj2){if(obj1 instanceof GoodsTest && obj2 instanceofGoodsTest){
GoodsTest goodsTestOne=(GoodsTest) obj1;
GoodsTest goodsTestTwo=(GoodsTest) obj2;if(((GoodsTest) obj1).getName().equals(((GoodsTest) obj2).getName())){return -Double.compare(((GoodsTest) obj1).getPrice(),((GoodsTest) obj2).getPrice());
}else{//return ((GoodsTest) obj1).getName().compareTo(((GoodsTest) obj2).getName());
return -Double.compare(((GoodsTest) obj1).getPrice(), ((GoodsTest) obj2).getPrice());
}
}throw new RuntimeException("输入的不对");
}
});
System.out.println(Arrays.toString(arry));//[GoodsTest{name='laowang', price=123.0}, GoodsTest{name='laoliu', price=113.0}, GoodsTest{name='laozhang', price=103.0}, GoodsTest{name='laoli', price=100.0}, GoodsTest{name='laohong', price=78.0}]
}
}classGoodsTest {privateString name;private doubleprice;publicString getName() {returnname;
}public doublegetPrice() {returnprice;
}public voidsetName(String name) {this.name =name;
}public void setPrice(doubleprice) {this.price =price;
}
@OverridepublicString toString() {return "GoodsTest{" +
"name='" + name + '\'' +
", price=" + price +
'}';
}publicGoodsTest(){}public GoodsTest(String name, doubleprice){this.name =name;this.price =price;
}
}
自然排序 和定制排序的区别:
Comparable 一旦指定 可以保证 它的实现类再任何位置都可以进行比较
Comparator 接口属于临时性的只在实现位置进行比较
两者好比一次性筷子和非临时性筷子的区别
Comparator是一次性的