- compareTo 方法是接口 Comparable 的实现
返回值是整型,它是先比较对应字符的大小(ASCII码顺序),如果第一个字符和参数的第一个字符不等,结束比较,返回他们之间的长度差值,如果第一个字符和参数的第一个字符相等,则以第二个字符和参数的第二个字符做比较,以此类推,直至比较的字符或被比较的字符有一方结束。
如果参数字符串等于此字符串,则返回值 0;如果此字符串小于字符串参数,则返回一个小于 0 的值;如果此字符串大于字符串参数,则返回一个大于 0 的值。
说明:
如果第一个字符和参数的第一个字符不等,结束比较,返回第一个字符的ASCII码差值。
如果第一个字符和参数的第一个字符相等,则以第二个字符和参数的第二个字符做比较,以此类推,直至不等为止,返回该字符的ASCII码差值。 如果两个字符串不一样长,可对应字符又完全一样,则返回两个字符串的长度差值。
Integer 和 String 实现了compareTo 方法
实体对象实现方法
package com.study.stream; import java.util.Objects; public class Person implements Comparable{ private String name; private Integer age; private Integer height; public Person(String name, Integer age, Integer height) { this.name = name; this.age = age; this.height = height; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Integer getHeight() { return height; } public void setHeight(Integer height) { this.height = height; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; return name.equals(person.name) && age.equals(person.age); } @Override public int hashCode() { return Objects.hash(name, age); } @Override public String toString() { return String.format("姓名:%s;年龄:%s;身高:%s;",this.name,this.age,this.height); } @Override public int compareTo(Person o) { return this.getAge().compareTo(o.getAge()); } }
实体对象排序:
2.Comparator 接口
Java提供了一个用于比较的接口Comparable,提供了一个比较的方法,所有实现该接口的类,都动态的实现了该比较方法。实际上Java中除了比较一个接口外,还提供了一个接口,该接口也是具有比较的功能,但该接口注重的却是比较容器,然后对其排序,这就是Comparator
源码:
package java.util; import java.io.Serializable; import java.util.function.Function; import java.util.function.ToIntFunction; import java.util.function.ToLongFunction; import java.util.function.ToDoubleFunction; import java.util.Comparators; @FunctionalInterface public interface Comparator{ int compare(T o1, T o2); boolean equals(Object obj); default Comparator reversed() { return Collections.reverseOrder(this); } default Comparator thenComparing(Comparator super T> other) { Objects.requireNonNull(other); return (Comparator & Serializable) (c1, c2) -> { int res = compare(c1, c2); return (res != 0) ? res : other.compare(c1, c2); }; } default Comparator thenComparing( Function super T, ? extends U> keyExtractor, Comparator super U> keyComparator) { return thenComparing(comparing(keyExtractor, keyComparator)); } default > Comparator thenComparing( Function super T, ? extends U> keyExtractor) { return thenComparing(comparing(keyExtractor)); } default Comparator thenComparingInt(ToIntFunction super T> keyExtractor) { return thenComparing(comparingInt(keyExtractor)); } default Comparator thenComparingLong(ToLongFunction super T> keyExtractor) { return thenComparing(comparingLong(keyExtractor)); } default Comparator thenComparingDouble(ToDoubleFunction super T> keyExtractor) { return thenComparing(comparingDouble(keyExtractor)); } public static > Comparator reverseOrder() { return Collections.reverseOrder(); } @SuppressWarnings("unchecked") public static > Comparator naturalOrder() { return (Comparator ) Comparators.NaturalOrderComparator.INSTANCE; } public static Comparator nullsFirst(Comparator super T> comparator) { return new Comparators.NullComparator<>(true, comparator); } public static Comparator nullsLast(Comparator super T> comparator) { return new Comparators.NullComparator<>(false, comparator); } public static Comparator comparing( Function super T, ? extends U> keyExtractor, Comparator super U> keyComparator) { Objects.requireNonNull(keyExtractor); Objects.requireNonNull(keyComparator); return (Comparator & Serializable) (c1, c2) -> keyComparator.compare(keyExtractor.apply(c1), keyExtractor.apply(c2)); } public static > Comparator comparing( Function super T, ? extends U> keyExtractor) { Objects.requireNonNull(keyExtractor); return (Comparator & Serializable) (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2)); } public static Comparator comparingInt(ToIntFunction super T> keyExtractor) { Objects.requireNonNull(keyExtractor); return (Comparator & Serializable) (c1, c2) -> Integer.compare(keyExtractor.applyAsInt(c1), keyExtractor.applyAsInt(c2)); } public static Comparator comparingLong(ToLongFunction super T> keyExtractor) { Objects.requireNonNull(keyExtractor); return (Comparator & Serializable) (c1, c2) -> Long.compare(keyExtractor.applyAsLong(c1), keyExtractor.applyAsLong(c2)); } public static Comparator comparingDouble(ToDoubleFunction super T> keyExtractor) { Objects.requireNonNull(keyExtractor); return (Comparator & Serializable) (c1, c2) -> Double.compare(keyExtractor.applyAsDouble(c1), keyExtractor.applyAsDouble(c2)); } }
案例:
List list; 代表某集合
//返回 对象集合以类属性一升序排序
list.stream().sorted(Comparator.comparing(类::属性一));
//返回 对象集合以类属性一降序排序 注意两种写法
list.stream().sorted(Comparator.comparing(类::属性一).reversed());
//先以属性一升序,结果进行属性一降序
list.stream().sorted(Comparator.comparing(类::属性一,Comparator.reverseOrder()));
//以属性一降序
//返回 对象集合以类属性一升序 属性二升序
list.stream().sorted(Comparator.comparing(类::属性一).thenComparing(类::属性二));
//返回 对象集合以类属性一降序 属性二升序 注意两种写法
list.stream().sorted(Comparator.comparing(类::属性一).reversed().thenComparing(类::属性二));
//先以属性一升序,升序结果进行属性一降序,再进行属性二升序
list.stream().sorted(Comparator.comparing(类::属性一,Comparator.reverseOrder()).thenComparing(类::属性二));
//先以属性一降序,再进行属性二升序
//返回 对象集合以类属性一降序 属性二降序 注意两种写法
list.stream().sorted(Comparator.comparing(类::属性一).reversed().thenComparing(类::属性二,Comparator.reverseOrder()));
//先以属性一升序,升序结果进行属性一降序,再进行属性二降序
list.stream().sorted(Comparator.comparing(类::属性一,Comparator.reverseOrder()).thenComparing(类::属性二,Comparator.reverseOrder()));
//先以属性一降序,再进行属性二降序
//返回 对象集合以类属性一升序 属性二降序 注意两种写法
list.stream().sorted(Comparator.comparing(类::属性一).reversed().thenComparing(类::属性二).reversed());
//先以属性一升序,升序结果进行属性一降序,再进行属性二升序,结果进行属性一降序属性二降序
list.stream().sorted(Comparator.comparing(类::属性一).thenComparing(类::属性二,Comparator.reverseOrder()));
//先以属性一升序,再进行属性二降序
通过以上例子我们可以发现
1. Comparator.comparing(类::属性一).reversed();
2. Comparator.comparing(类::属性一,Comparator.reverseOrder());
两种排序是完全不一样的,一定要区分开来 1 是得到排序结果后再排序,2是直接进行排序,很多人会混淆导致理解出错,2更好理解,建议使用
代码:
System.out.println("***************--sorted 定义排序规则 身高,年龄排序--***************************");
personList.stream().sorted(Comparator.comparing(Person::getHeight,Comparator.naturalOrder()).thenComparing(Person::getAge,Comparator.naturalOrder())).forEach(System.out::println);



