Java Comparator.comparing比较导致空指针异常的解决

网友投稿 301 2022-12-28

Java Comparator.comparing比较导致空指针异常的解决

java Comparator.comparing比较导致空指针异常

Comparator.comparing(Department::getOrder)

原因:

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));

}

如果keyExtractor.apply(c1),那么keyExtractor.apply(c1).compareTo(XX)将报空指针异常

替代方案

Comparator.comparing(Department::getOrder, Comparator.nullsFirst(Comparator.naturalOrder()))

替代方案好处:

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));

}

会先取出keyExtractor.apply(c1)和keyExtractor.apply(c2),放入比较器进行比较

而Comparator.nullsFirst作为比较器,会创建一个Comparators.NullComparator比较器

public static Comparator nullsFirst(Comparator super T> comparator) {

return new Comparators.NullComparator<>(true, comparator);

}

Comparators.NullComparator比较器的compare接口实现中先进行空值判断处理,不为空的再进行代入比较器比较

/**

* Null-friendly comparators

*/

final static class NullComparator implements Comparator, Serializable {

private static final long serialVersionUID = -7569533591570686392L;

private final boolean nullFirst;

// if null, non-null Ts are considered equal

private final Comparator real;

@SuppressWarnings("unchecked")

NullComparator(boolean nullFirst, Comparator super T> real) {

this.nullFirst = nullFirst;

this.real = (Comparator) 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);

}

}

@Override

public Comparator thenComparing(Comparator super T> other) {

Objects.requireNonNull(other);

return new NullComparator<>(nullFirst, real == null ? other : real.thenComparing(other));

}

@Override

public Comparator reversed() {

return new NullComparator<>(!nullFirst, real == null ? null : real.reversed());

}

}

Comparator中comparing方法的学习

例子:

我们需要根据对象中的name字段进行不规则排序

排序规则为(PPD > 政府 > 合作)

public class Obj {

private String name;

private BigDecimal price;

......

}

@Test

public void sort() {

List list = Arrays.asList(

new Obj("政府", null),

new Obj("政府", new BigDecimal("1216.23")),

new Obj("商业", new BigDecimal("123.23")),

new Obj("PPD", new BigDecimal("123.23")),

new Obj("合作", new BigDecimal("127.23")),

new Obj(null, new BigDecimal("125.23")));

List sortList = Arrays.asList("PPD","政府","合作");

List result = list.stream().sorted(

//先按照name排序(模拟需求的a属性排序)

Comparator.comparing(Obj::getName,(x,y)-> {

if(x == null && y != null){

http:// return 1;

}else if(x !=null && y == null){

return -1;

}else if(x == null && y == null){

return -1;

} else {

for(String sort : sortList){

if(sort.equals(x) || sort.equals(y)){

if(x.equals(y)){

return 0;

}else ifvXSzsY(sort.equals(x)){

return -1;

}else{

return 1;

}

}

}

return 0;

}

})).collect(Collectors.toList());

System.out.println(result);

}

1.实现

comparing方法有两种实现

方法2:

问:这个方法中泛型是怎么传递的

1、list.stream()时,获取的stream流已经确定了泛型了,此时返回的对象为Stream

2、Stream对象的sorted方法,需要比较器的类型需要是Obj.calss或者是Obj的父类

3、而我们这边调用了静态方法Comparator.comparing,静态方法中的泛型是根据传的参数中的类型来决定的

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:网站数据api接口吗(数据API接口)
下一篇:带你了解Spring AOP的使用详解
相关文章

 发表评论

暂时没有评论,来抢沙发吧~