琼山网站制作,在线短网址缩短工具,网络营销公司加盟,门图书馆户网站建设方案问题引出
起初#xff0c;写了一行排序代码#xff0c;空指针异常。有判空思想但对nullsLast理解是错误的#xff0c;于是阅读了一下相关源码。
result.sort(Comparator.nullsLast(Comparator.comparing(StationPointDataZoneVO::getDv)));以下写法是正确的#xff1a;
…问题引出
起初写了一行排序代码空指针异常。有判空思想但对nullsLast理解是错误的于是阅读了一下相关源码。
result.sort(Comparator.nullsLast(Comparator.comparing(StationPointDataZoneVO::getDv)));以下写法是正确的
result.sort(Comparator.comparing(StationPointDataZoneVO::getDv, Comparator.nullsFirst(Comparator.comparing(Function.identity()))).reversed());接下来以Comparator 接口为引探究一下比较器各个方法的正确用法。
Comparator.comparing
有两个核心方法
public static T, U ComparatorT comparing(Function? super T, ? extends U keyExtractor,Comparator? super U keyComparator)
{Objects.requireNonNull(keyExtractor);Objects.requireNonNull(keyComparator);return (ComparatorT Serializable)(c1, c2) - keyComparator.compare(keyExtractor.apply(c1),keyExtractor.apply(c2));
}public static T, U extends Comparable? super U ComparatorT comparing(Function? super T, ? extends U keyExtractor)
{Objects.requireNonNull(keyExtractor);return (ComparatorT Serializable)(c1, c2) - keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
}先说下面一个传入一个取值函数一般情况是以某字段为依据给对象排序如 StationPointDataZoneVO::getDv。比较自身 Function.identity() 即可。返回一个Comparator接口的具体实现需要注意的是比较器最终调用的方法是实现了Comparable接口的某个对象的compareTo方法。
第一个方法传入两个参数一个取值函数一个比较器。最终调用比较器的compare方法。 以下写法效果一样同样使用某对象自己实现的compareTo方法。
result.sort(Comparator.comparing(StationPointDataZoneVO::getDv));
result.sort(Comparator.comparing(StationPointDataZoneVO::getDv, Comparator.comparing(Function.identity())));
result.sort(Comparator.comparing(StationPointDataZoneVO::getDv, Comparator.naturalOrder()));Comparator.thenComparing
thenComparing有好几个方法本质都调用的这个。
default ComparatorT thenComparing(Comparator? super T other) {Objects.requireNonNull(other);return (ComparatorT Serializable) (c1, c2) - {int res compare(c1, c2);return (res ! 0) ? res : other.compare(c1, c2);};
}不难看懂就是上一个比较器结果相等时调用下一个比较器可以嵌套很多层。
Comparator.naturalOrder nullsFirst nullsLast
这三个有一个共同特点返回 Comparators类中的某个比较器实例。
NaturalOrderComparator enum NaturalOrderComparator implements ComparatorComparableObject {INSTANCE;Overridepublic int compare(ComparableObject c1, ComparableObject c2) {return c1.compareTo(c2);}Overridepublic ComparatorComparableObject reversed() {return Comparator.reverseOrder();}}NullComparator
构造器和核心方法
NullComparator(boolean nullFirst, Comparator? super T real) {this.nullFirst nullFirst;this.real (ComparatorT) real;
}Override
public int compare(T a, T b) {if (a null) {return (b null) ? 0 : (nullFirst ? -1 : 1);} else if (b null) {return nullFirst ? 1: -1;} else {return (real null) ? 0 : real.compare(a, b);}
}回到开篇的问题为何会报空指针就不难理解 进入到NullComparator的compare后a和b其实是StationPointDataZoneVO对象它确实不为null。于是调用传入的比较器的compare方法最终调用到的是 (StationPointDataZoneVO::getDv).compareTo(StationPointDataZoneVO::getDv). dv取值为null于是空指针。
Comparator.reversed reverseOrder
此时牵扯进来了另一个类Collections。 reversed 和reverseOrder分别返回Collections定义的ReverseComparator2比较器和ReverseComparator比较器。 这两个比较器的区别是前者用传入的比较器做翻转比较即compare方法参数翻转
public int compare(T t1, T t2) {return cmp.compare(t2, t1);
}后者直接翻转调用compareTo
public int compare(ComparableObject c1, ComparableObject c2) {return c2.compareTo(c1);
}Comparators
此类用于支持Comparator接口提供两个比较器NaturalOrderComparatorNullComparator
Collections
也提供了两个比较器ReverseComparatorReverseComparator2