1 相同点
- Comparable、Comparator 都是用来实现集合中元素的比较、排序的。
2 不同点
- Comparator位于包 java.util、Comparable位于包 java.lang;
- Comparator 是在集合外部实现的排序,Comparable 是在集合内部定义的方法实现的排序;
- 实现 Comparator 需要覆盖 compare 方法,compare 方法里面实现比较。好处是不需要修改源代码, 而是另外实现一个比较器。
- 实现 Comparable 接口要覆盖 compareTo 方法, 在 compareTo 方法里面实现比较。
3 自然排序
- Java 常见类如 String、Integer 等都已实现 Comparable 接口,都有自己独特的排序规则。
- 元素自身所具有的排序规则称为:自然排序。
4 代码示例
Apple 类–实现 Comparable 接口
/**
* 实现Comparable接口
* 类的对象拥有比较特性,
* 在类的内部实现compareTo()方法
* @version $Id: Apple.java, v 0.1 2017年7月22日 下午6:37:34
*/
public class Apple implements Comparable<Apple>, Serializable {
/** */
private static final long serialVersionUID = 7844213446947863973L;
private String name;
private Double price;
public Apple(String name, Double price) {
super();
this.name = name;
this.price = price;
}
/**
* 先按名字排序,名字相同按价格排序
* @see java.lang.Comparable#compareTo(java.lang.Object)
*/
@Override
public int compareTo(Apple otherApple) {
int flag = name.compareTo(otherApple.name);
//名字相同,比价格
if (flag == 0) {
//Double类型自身实现Comparable接口
return price.compareTo(otherApple.price);
}
return flag;
}
@Override
public String toString() {
return "Apple [name=" + name + ", price=" + price + "]";
}
}
Egg 类
/**
* @version $Id: Egg.java, v 0.1 2017年7月22日 下午6:58:25
*/
public class Egg implements Serializable {
/** */
private static final long serialVersionUID = 5635366463709253737L;
private String name;
private Double price;
public Egg(String name, Double price) {
super();
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 "Egg [name=" + name + ", price=" + price + "]";
}
}
EggComparator --比较器, 实现 Comparator 接口
/**
* 实现Comparator接口,
* 在类的外部实现一个与类相关的比较器,
* 实现compare()方法,
* 可以对一个类从不同的维度实现多个比较器,
* 控制更加灵活
*
* @version $Id: EggComparator.java, v 0.1 2017年7月22日 下午6:58:17
*/
public class EggComparator implements Comparator<Egg> {
/**
* 先按名字排序,名字相同按价格排序
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
*/
@Override
public int compare(Egg one, Egg another) {
int flag = one.getName().compareTo(another.getName());
//名字相同比价格
if (flag == 0) {
return one.getPrice().compareTo(another.getPrice());
}
return flag;
}
}
测试类
/**
* @version $Id: TestCase.java, v 0.1 2017年7月22日 下午7:17:51
*/
public class TestCase {
@Test
public void test() {
ArrayList<Apple> list = new ArrayList<>();
list.add(new Apple("apple", 3.0));
list.add(new Apple("apple", 2.0));
list.add(new Apple("apple", 1.0));
list.add(new Apple("apple1", 2.0));
list.add(new Apple("apple1", 1.0));
System.out.println("----排序前----");
list.forEach((item) -> System.out.println(item + ";"));
//排序
Collections.sort(list);
System.out.println("----排序后----");
list.forEach((item) -> System.out.println(item + ";"));
System.out.println("================");
ArrayList<Egg> arrays = new ArrayList<>();
arrays.add(new Egg("egg1", 3.0));
arrays.add(new Egg("egg1", 2.0));
arrays.add(new Egg("egg1", 1.0));
arrays.add(new Egg("egg", 2.0));
arrays.add(new Egg("egg", 1.0));
System.out.println("----排序前----");
arrays.forEach((item) -> System.out.println(item + ";"));
//排序,比较器作为入参
Collections.sort(arrays, new EggComparator());
System.out.println("----排序后----");
arrays.forEach((item) -> System.out.println(item + ";"));
}
}
测试结果:
----排序前----
Apple [name=apple, price=3.0];
Apple [name=apple, price=2.0];
Apple [name=apple, price=1.0];
Apple [name=apple1, price=2.0];
Apple [name=apple1, price=1.0];
----排序后----
Apple [name=apple, price=1.0];
Apple [name=apple, price=2.0];
Apple [name=apple, price=3.0];
Apple [name=apple1, price=1.0];
Apple [name=apple1, price=2.0];
================
----排序前----
Egg [name=egg1, price=3.0];
Egg [name=egg1, price=2.0];
Egg [name=egg1, price=1.0];
Egg [name=egg, price=2.0];
Egg [name=egg, price=1.0];
----排序后----
Egg [name=egg, price=1.0];
Egg [name=egg, price=2.0];
Egg [name=egg1, price=1.0];
Egg [name=egg1, price=2.0];
Egg [name=egg1, price=3.0];