Comparator和Comparable之间的区别
2017-11-22 21:16
369 查看
简介
Comparable接口
Comparator接口
Comparator和Comparable的区别
栗子
实现了comparable接口类的
自然排序中,
实际上,所有实现comparable的类中方法
1,入参一大于入参二。
0,入参相同。
-1,入参一小于入参二。
实现的类必须保证以下 要求:
通常情况下,实现Comparator的类并不被严格要求要遵循
实现Comparator的接口的
如果有多个比较规则,可以充分利用
参考资料
Comparable接口
Comparator接口
Comparator和Comparable的区别
栗子
简介
Comparable接口
该接口对每个实现它的类的对象强加了排序规则。该排序称之为自然排序(natural ordering)。方法public int compareTo(T o)是自然排序的排序方法。
实现了comparable接口类的
List或者arrays对象可以通过调用以下方法进行排序:
1. Collections#sort(List<T> list) //内部是调用第二个方法进行排序 2. Arrays#sort(Object[] a) //算法是合并排序或二分排序 n^2算法复杂度 //此外,可以通过将元素添加到一下集合或Map中实现排序 3. SortedMap tm = new TreeMap(); 4. SortedSet ts = new TreeSet();
自然排序中,
e1.compareTo(e2) == 0的布尔值应该等价于
e1.equals(e2)。注意
null不属于任何类的实例,故
e.compareTo(null)应抛出空指针异常,尽管此时
e.equals(null)为
false。
实际上,所有实现comparable的类中方法
compareTo和
equals方法值是等价的。一个特例就是
java.math.BigDecimal。
Comparator接口
通过比较两个入参得到顺序。返回值有三种:1,入参一大于入参二。
0,入参相同。
-1,入参一小于入参二。
实现的类必须保证以下 要求:
sgn(compare(x, y)) == -sgn(compare(y, x))。暗示着
compare(x, y)抛异常,则
compare(y,x)也抛异常。
((compare(x, y) < 0),((compare(y,z) < 0)暗示着
((compare(x,z) < 0)。
compare(x, y)==0暗示着
sgn(compare(x, z))==sgn(compare(y, z))。
通常情况下,实现Comparator的类并不被严格要求要遵循
(compare(x, y)==0) == (x.equals(y)),但是违反该条件的应该明确地指出这一事实,即说明条件
(compare(x, y)==0) == (x.equals(y))并不成立。
实现Comparator的接口的
List或者arrays对象可以通过调用以下方法进行排序:
1. Collections#sort(List<T> list,, Comparator<? super T> c) //内部是调用第二个方法进行排序 2. Arrays#sort(Object[] a, Comparator<? super T> c) //算法是合并排序或二分排序 n^2算法复杂度 //此外还可以通过将对象加入以下集合或Map实现排序 3. SortedMap tm = new TreeMap(Comparator<? super K> comparator); 4. SortedSet ts = new TreeSet(Comparator<? super K> comparator);
如果有多个比较规则,可以充分利用
Comparator接口的默认方法:
default Comparator<T> thenComparing(Comparator<? super T> other) { Objects.requireNonNull(other); return (Comparator<T> & Serializable) (c1, c2) -> { int res = compare(c1, c2); return (res != 0) ? res : other.compare(c1, c2); }; }
Comparator和Comparable的区别
参数 | Comparable | Comparator |
---|---|---|
排序逻辑 | 排序逻辑必须在待排序对象的类中,故称之为自然排序 | 排序逻辑在另一个实现 |
实现 | 实现Comparable接口 | 实现Comparator接口 |
排序方法 | int compareTo(Object o1) | int compare(Object o1,Object o2) |
触发排序 | Collections.sort(List) | Collections.sort(List, Comparator) |
接口所在包 | java.lang.Comparable | java.util.Comparator |
栗子
假设我们想要人类先以姓名升序排序,假如姓名一样则按照年龄排序,则代码可以如下:Person.java
@Data @NoArgsConstructor @AllArgsConstructor /** * @author hjb */ public class Person implements Comparable { private String name; private Integer age; private String mind; @Override public int compareTo(Object o) { Person targetPerson = (Person)o; int ret = this.name.compareTo(targetPerson.getName()); if(ret == 0){ return Integer.compare(this.age,targetPerson.getAge()); } if(ret == 0){ return this.getMind().compareTo(targetPerson.getMind()); } return ret; } }
PersonComparator.java
public class PersonComparator implements Comparator<Person> { @Override public int compare(Person p, Person p2) { int ret = p.getName().compareTo(p2.getName()); if(ret == 0){ return p.getAge().compareTo(p2.getAge()); } return ret; } }
PersonComparator2.java
public class PersonComparator2 implements Comparator<Person> { @Override public int compare(Person p, Person p2) { return p.getMind().compareTo(p2.getMind()); } }
TestCompare.java
public class TestComparable { public static void main(String[] args){ //取数据 List<Person> personList = generatePersonList(); //排序一: 正常 Collections.sort(personList); print("Collections.sort(list)",personList); //排序二:发现正常了 PersonComparator pc = new PersonComparator(); PersonComparator2 pc2 = new PersonComparator2(); bdfa Collections.sort(personList,pc.thenComparing(pc2)); print("thenComparing",personList); //排序三:正常 SortedSet<Person> ts = new TreeSet<>(personList); print("TreeSet",ts); //排序四:发现某个Person实例被吃掉了,因为TreeSet认为CompareTo为0,则两个Person实例相同 SortedSet<Person> ts2 = new TreeSet<>(new PersonComparator()); ts2.addAll(personList); print("TreeSet(Comparator)",ts2); } //生成待排序数组 private static List<Person> generatePersonList() { List<Person> retList = new ArrayList<>(16); retList.addAll( Arrays.asList( new Person[]{ new Person("erMaZi", 19, "good"), new Person("liSi", 17, "bad"), new Person("wangWu", 18, "middle"), new Person("wangWu", 18, "middla"), } ) ); return retList; } public static void print(String message,List<Person> personList){ System.out.println(message+":"); for(Person p:personList){ System.out.println(p); } System.out.println(); } public static void print(String message,SortedSet<Person> sortedSet){ System.out.println(message+":"); for(Person p:sortedSet){ System.out.println(p); } System.out.println(); } }
Output
Collections.sort(list): Person(name=erMaZi, age=19, mind=good) Person(name=liSi, age=17, mind=bad) Person(name=wangWu, age=18, mind=middla) Person(name=wangWu, age=18, mind=middle) thenComparing: Person(name=erMaZi, age=19, mind=good) Person(name=liSi, age=17, mind=bad) Person(name=wangWu, age=18, mind=middla) Person(name=wangWu, age=18, mind=middle) TreeSet: Person(name=erMaZi, age=19, mind=good) Person(name=liSi, age=17, mind=bad) Person(name=wangWu, age=18, mind=middla) Person(name=wangWu, age=18, mind=middle) TreeSet(Comparator): Person(name=erMaZi, age=19, mind=good) Person(name=liSi, age=17, mind=bad) Person(name=wangWu, age=18, mind=middla)
参考资料
相关文章推荐
- Comparator和Comparable的区别使用
- comparator接口与Comparable接口的区别
- Comparable与Comparator的区别
- Java中 Comparator接口 与Comparable 的区别
- Java中Comparable和Comparator区别
- Comparator接口与Comparable接口的区别
- comparator接口与Comparable接口的区别
- Comparable和Comparator的区别
- Comparable与Comparator的区别
- SunnyAmy comparator接口与Comparable接口的区别
- comparable和comparator的区别
- comparator接口与Comparable接口的区别
- 关于comparator以及comparable的区别及应用
- Comparable与Comparator的区别
- Java中,如果想要排序,实现Comparator接口 //与Comparable 的区别?
- comparator接口与Comparable接口的区别
- Comparable与Comparator的区别
- comparator接口与Comparable接口的区别
- comparator接口与Comparable接口的区别
- java中Comparator 和 Comparable 的区别