Java函数式接口之Comparable
Java函数式接口之Comparable
Java函数式接口之Comparable
-able接口 在Java中一般表示能力,例如Comparable 比较能力,Iterable迭代能力等等
1. Comparable接口
Comparable接口,如其名,实现它后,实现类具有比较比较能力。在Java中是一个FunctionalInterface接口,里面包含一个compareTo方法
这里引入源代码来分析, 具体如下:
- 实现该接口的每个类对象会被强加一个总排序,被称之为自然排序,compareTo方法被称之为自然排序法
- List、Array等对象实现了该接口,可以自动排序。
- compareTo禁止接收null值 会抛出空指针异常,null不是任何类的实例
- 强烈推荐自然排序和equal结果是一致的,例如 compareTo一致相当于equal方法返回true, 但未要求
- compareTo 使用特定对象来比较顺序 返回 一个负数 或者 0 或者正数 来表示 小于 等于 大于
- compareTo必须满足交换性、传递性等特性
- 排序输出默认是升序
public interface Comparable<T> {
/**
* 使用特定对象来比较顺序 返回 一个负数 或者 0 或者正数 来表示 小于 等于 大于
* Compares this object with the specified object for order. Returns a
* negative integer, zero, or a positive integer as this object is less
* than, equal to, or greater than the specified object.
* 必须确保交换性 x.compareTo(y)的结果和y.compareTo(x)结果一致
* <p>The implementor must ensure <tt>sgn(x.compareTo(y)) ==
* -sgn(y.compareTo(x))</tt> for all <tt>x</tt> and <tt>y</tt>. (This
* implies that <tt>x.compareTo(y)</tt> must throw an exception iff
* <tt>y.compareTo(x)</tt> throws an exception.)
* 传递性
* <p>The implementor must also ensure that the relation is transitive:
* <tt>(x.compareTo(y)>0 && y.compareTo(z)>0)</tt> implies
* <tt>x.compareTo(z)>0</tt>.
*
* <p>Finally, the implementor must ensure that <tt>x.compareTo(y)==0</tt>
* implies that <tt>sgn(x.compareTo(z)) == sgn(y.compareTo(z))</tt>, for
* all <tt>z</tt>.
* 强烈推荐 x.compareTo比较相同的话 equals值也相等
* <p>It is strongly recommended, but <i>not</i> strictly required that
* <tt>(x.compareTo(y)==0) == (x.equals(y))</tt>. Generally speaking, any
* class that implements the <tt>Comparable</tt> interface and violates
* this condition should clearly indicate this fact. The recommended
* language is "Note: this class has a natural ordering that is
* inconsistent with equals."
* 一般来说 返回值 通常定义三种 -1、0或者 1 这类似一种约定 当然你负数 正数其他值也可以
* <p>In the foregoing description, the notation
* <tt>sgn(</tt><i>expression</i><tt>)</tt> designates the mathematical
* <i>signum</i> function, which is defined to return one of <tt>-1</tt>,
* <tt>0</tt>, or <tt>1</tt> according to whether the value of
* <i>expression</i> is negative, zero or positive.
*
* @param o the object to be compared.
* @return a negative integer, zero, or a positive integer as this object
* is less than, equal to, or greater than the specified object.
*
* @throws NullPointerException if the specified object is null
* @throws ClassCastException if the specified object's type prevents it
* from being compared to this object.
*/
public int compareTo(T o);
}
1. 已实现Comparable接口
- List集合,一般排序借助于Collections工具类
public static void listSort(){
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(8);
list.add(3);
//第一种排序方法
list.sort(null);
//第二种排序方法 底层使用第一种方法
Collections.sort(list);
System.out.println(list);
}
- Array排序 一般排序借助于Arrays工具类
//在原有基础上排序
public static void arraySort(){
int[] arr = {1,5,3,7};
//第一种排序
Arrays.sort(arr);
//第二种排序
int[] newArr = Arrays.stream(arr).sorted().toArray();
System.out.println(Arrays.toString(arr));
}
2. Comparator类
Comparator,一个比较的功能类,也是一个FunctionalInterface.提供了compare方法,接受两个参数,并返回比较值,比较值的规则和Comparable一致,
也可以实现Comparable相同的比较效果
//其他方法省略
@FunctionalInterface
public interface Comparator<T> {
/**比较两个参数顺序 返回 负数 0 或 正数 分别表示 小于 等于 大于
* Compares its two arguments for order. Returns a negative integer,
* zero, or a positive integer as the first argument is less than, equal
* to, or greater than the second.<p>
* 一般用 -1 0 1表示返回结果
* In the foregoing description, the notation
* <tt>sgn(</tt><i>expression</i><tt>)</tt> designates the mathematical
* <i>signum</i> function, which is defined to return one of <tt>-1</tt>,
* <tt>0</tt>, or <tt>1</tt> according to whether the value of
* <i>expression</i> is negative, zero or positive.<p>
*
* The implementor must ensure that <tt>sgn(compare(x, y)) ==
* -sgn(compare(y, x))</tt> for all <tt>x</tt> and <tt>y</tt>. (This
* implies that <tt>compare(x, y)</tt> must throw an exception if and only
* if <tt>compare(y, x)</tt> throws an exception.)<p>
*
* The implementor must also ensure that the relation is transitive:
* <tt>((compare(x, y)>0) && (compare(y, z)>0))</tt> implies
* <tt>compare(x, z)>0</tt>.<p>
*
* Finally, the implementor must ensure that <tt>compare(x, y)==0</tt>
* implies that <tt>sgn(compare(x, z))==sgn(compare(y, z))</tt> for all
* <tt>z</tt>.<p>
*
* It is generally the case, but <i>not</i> strictly required that
* <tt>(compare(x, y)==0) == (x.equals(y))</tt>. Generally speaking,
* any comparator that violates this condition should clearly indicate
* this fact. The recommended language is "Note: this comparator
* imposes orderings that are inconsistent with equals."
*
* @param o1 the first object to be compared.
* @param o2 the second object to be compared.
* @return a negative integer, zero, or a positive integer as the
* first argument is less than, equal to, or greater than the
* second.
* @throws NullPointerException if an argument is null and this
* comparator does not permit null arguments
* @throws ClassCastException if the arguments' types prevent them from
* being compared by this comparator.
*/
int compare(T o1, T o2);
}
3. Comparable和Comparator区别
Java设计了Comparable接口,那么为什么还需要设计Comparator接口呢,两者区别是什么呢。
首先Comparable接口和Comparator接口 都能提供比较能力并返回结果。这是他们的相同点,这是设计的初衷
不同点:
- Comparable 表示一种能力,一般需要对象实现其接口,使其获取比较的能力。实现后 相当于本身具有比较能力。直接调用compareTo方法
- Comparator 是一种工具,通过这种工具,可以将两种不具备比较的对象,区分出顺序。是借助外部工具
4. Java设计方式思考
Java中有其实还有其他类似的设计。例如Iterable和iterator.都是这样。针对相同的能力尽可能的提供更多的渠道,可以实现它,或者使用工具,最终的目的都是达到需要实现的目的。根据这种类似案例,是否以后在开发业务或工具时,也提供更多的渠道供其他调用者使用
5. 其他类似案例
Iterable和Iterator
6. 总结
本篇文章其实是FunctionalInterface函数式接口的扩展。在常用的Supplier、Consumer、Function、Predicate的FunctionalInterface以及各种类型扩展后。介绍了Comparable接口。并扩展介绍Comparable的功能含义以及Comparable和Comparator比较。
其实本篇在介绍Comparable接口功能时,列举的案例,输出结果都是都是升序的,那么你有没有想过,如果列举出倒序的结果呢,又有哪几种方式呢?