在Java中经常遇到数组和对象的排序问题,那么就涉及到对象之间的比较问题。
Java中的对象,正常情况下,只能进行比较:== !=。不能用 > < 号比较对象,使用以下方式比较对象的大小。
在Java中实现对象排序的两种方式:
①自然排序:java.lang.Comparable
②定制排序:java.util.Comparator
一个类实现Comparable接口,Comparable会强行对实现它的每个类进行整体排序。这种类的排序称为类的自然排序。
实现Comparable的类必须实现的Comparable中的compareTo(Object obj)方法,两个对象通过compareTo(Object obj)方法的返回值来比较大小。
如果当this对象大于形参的obj,则返回正整数;
如果当前this对象小于形参obj,则返回负整数;
如果当前对象的this等于形参obj,则返回0;
返回的是如果前面添加 负号,
// 返回的是自然排序从小到大,要从大到小的话,在前面添加负号 return -s1.compareTo(s2);
有的类已经实现了Comparable接口,比如String,重写了接口中的compareTo()方法,给出比较两个对象的大小。对于自定义的类来说,如果需要排序,我们可以自定义类实现Comparable接口,重写compareTo()方法进行排序。
注意:A instanceOf(B):意思是判断A是否是B的对象
具体自定义类的比较,需要实现Comparable接口,然后实现compareTo()方法。
public class Goods implements Comparable{ private String name; private Double price; public Goods(String name, Double price) { this.name = name; this.price = price; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Double getPrice() { return price; } public void setPrice(Double price) { this.price = price; } @Override public String toString() { return "Goods{" + "name='" + name + '\'' + ", price=" + price + '}'; } public int compareTo(Object o) { // 判断参数对象是否属于Goods if (o instanceof Goods) { // 将参数o强转Goods对象 Goods good = (Goods)o; if (this.price > good.price) { return 1; } else if (this.price < good.price) { return -1; } else { // return 0; // 当商品价格相同的时候,就从商品的名称开始排序 return this.name.compareTo(good.name); } // return Double.compare(this.price, good.price); } // 如果不是一个商品就抛出异常 throw new RuntimeException("运行时候异常"); } }
public void test3(){ String[] arr = new String[]{"ZZ","KK","QQ","WW"}; Arrays.sort(arr, new Comparator<String>() { @Override public int compare(String o1, String o2) { // 两个对象都应该是String类似,满足才比较 if (o1 instanceof String && o2 instanceof String) { // 进行强转 String s1 = (String) o1; String s2 = (String) o2; // 返回的是自然排序从小到大,要从大到小的话,在前面添加负号 return -s1.compareTo(s2); } throw new RuntimeException("运行时候异常"); } }); System.out.println(Arrays.toString(arr)); }
当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码,或者实现了java.lang.Comparable接口的排序规则而不适合的操作,那么可以使用Comparator的对象来排序。
在sort()方法中的第二个参数实现Comparator(){},判断对象的大小。
compare(Object obj,Object obj),比较o1和o2的大小:如果方法放回正整数,则o1大于o2;如果返回0,表示相等;返回负整数,表示o1小于o2;
注意:int compare(T o1,T o2):意思是判断A是否是B的对象
代码如下:实现的是如果name相同,就比较price。否则就按照姓名排序。
@Test public void test4(){ Goods[] goods = new Goods[5]; goods[0] = new Goods("qwq", 12.0); goods[1] = new Goods("dwe", 13.0); goods[2] = new Goods("awqeq", 54.0); goods[3] = new Goods("yh", 1000.0); goods[4] = new Goods("yh", 123.0); Arrays.sort(goods, new Comparator<Goods>() { @Override public int compare(Goods o1, Goods o2) { if (o1.getName().equals(o2.getName())) { return o1.getPrice().compareTo(o2.getPrice()); } else { return o1.getName().compareTo(o2.getName()); } } }); System.out.println(Arrays.toString(goods)); }
本文是主要讲的是Java中的比较器,现在来做个总结。
①自然比较:java.lang.Comparable,接口中的方法public int compareTo(T o);
②定制比较:java.util.Comparator , 接口中的方法 int compare(T o1,T o2)
比较:
Comparable接口的方式一旦确定,保证Comparable接口实现实现类的对象在任何位置比较大小。
Comparator接口属于临时性比较,相当于一次性的,程序自己写。