GVKun编程网logo

第二章 一节spring-core之comparator深入解读(spring-core详解)

29

本文将分享第二章一节spring-core之comparator深入解读的详细内容,并且还将对spring-core详解进行详尽解释,此外,我们还将为大家带来关于Comparator.comparin

本文将分享第二章 一节spring-core之comparator深入解读的详细内容,并且还将对spring-core详解进行详尽解释,此外,我们还将为大家带来关于Comparator.comparing排序使用示例、FixedOrderComparator BeanComparator 实现指定排序、Java Comparator comparingInt() 的使用、Java Comparator.comparing 比较导致空指针异常的解决的相关知识,希望对你有所帮助。

本文目录一览:

第二章 一节spring-core之comparator深入解读(spring-core详解)

第二章 一节spring-core之comparator深入解读(spring-core详解)

前言

本章节深入讲解spring的comparator,使用与细节,帮助大家在项目里面正确使用comparator。源码解读无法通过文字很详细的解释,诠释。需要读者多次阅读,深入理解,组织逻辑,大脑慢慢形成整个流程。

从深入理解java api中的comparator,在脑海中形成一个技术蓝图

private Comparator<Integer> comparator = new Comparator<Integer>() {
	    @Override
	    public int compare(Integer o1, Integer o2) {
			if(o1 == o2){
				return 0;
			}
		return o1 > o2?1:-1;
	    }
	};

public void comparatorTest(){
	Random random = new Random();
	List<Integer> intList = new ArrayList<>();
	for(int i = 0 ; i< 20 ; i++){
	    intList.add(random.nextInt(40));
	}
	log.info("intList里面的数据,现在是无序的:" + intList);
	
	Collections.sort(intList, comparator);
	log.info("排序之后的结果:" + intList.toString());
}

结果

2018-04-01 11:27:44.455 [main] INFO  c.n.b.spring.core.ordere.OrdereTest - intList里面的数据,现在是无序的:[26, 21, 18, 35, 25, 14, 15, 17, 15, 13, 37, 15, 35, 29, 13, 19, 32, 15, 19, 12]
2018-04-01 11:27:44.479 [main] INFO  c.n.b.spring.core.ordere.OrdereTest - 排序之后的结果:[12, 13, 13, 14, 15, 15, 15, 15, 17, 18, 19, 19, 21, 25, 26, 29, 32, 35, 35, 37]

  1. 需要comparator的实现类
  2. 实例化comparator的子类
  3. 保存实例化结果
  4. 调用Collections.sort(intList, comparator);触发排序

流程分析

按照上面comparator的流程,在spring中寻找对应的流程。

需要comparator的实现类,与基本体系

spring 里面comparator的有两个子类分别是OrderComparator,AnnotationAwareOrderComparator 输入图片说明

实例化comparator的子类

comparator的子类都会在当前类里面声明一个该类的静态不可变的变量

public class OrderComparator implements Comparator<Object> {
	public static final OrderComparator INSTANCE = new OrderComparator();
}
public class AnnotationAwareOrderComparator extends OrderComparator {
	public static final AnnotationAwareOrderComparator INSTANCE = new AnnotationAwareOrderComparator();
}

保存实例化结果

在DefaultListableBeanFactory里面声明了一个Comparator类型的dependencyComparator变量,用于对bean进行排序

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
		implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
		
	/** Optional OrderComparator for dependency Lists and arrays */
	private Comparator<Object> dependencyComparator;
}

一旦使用AnnotatedBeanDefinitionReader与ClassPathBeanDefinitionScanner,就会加载AnnotationAwareOrderComparator

public class AnnotationConfigUtils {
	public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
			BeanDefinitionRegistry registry, Object source) {

		DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
		if (beanFactory != null) {
			if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
				beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
			}
		}
	.....
	}
}

调用Collections.sort(intList, comparator)触发排序

对BeanFactoryPostProcessor及子类的list接口进行排序

class PostProcessorRegistrationDelegate {
	private static void sortPostProcessors(ConfigurableListableBeanFactory beanFactory, List<?> postProcessors) {
		Comparator<Object> comparatorToUse = null;
		if (beanFactory instanceof DefaultListableBeanFactory) {
			comparatorToUse = ((DefaultListableBeanFactory) beanFactory).getDependencyComparator();
		}
		if (comparatorToUse == null) {
			comparatorToUse = OrderComparator.INSTANCE;
		}
		Collections.sort(postProcessors, comparatorToUse);
	}
}

在调用getBean,如果是返回结果是List或者是Array.就会进行排序

private Object resolveMultipleBeans(DependencyDescriptor descriptor, String beanName,
			Set<String> autowiredBeanNames, TypeConverter typeConverter) {

		Class<?> type = descriptor.getDependencyType();
		if (type.isArray()) {
			Class<?> componentType = type.getComponentType();
			Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType,
					new MultiElementDescriptor(descriptor));
			if (matchingBeans.isEmpty()) {
				return null;
			}
			if (autowiredBeanNames != null) {
				autowiredBeanNames.addAll(matchingBeans.keySet());
			}
			TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
			Object result = converter.convertIfNecessary(matchingBeans.values(), type);
			if (getDependencyComparator() != null && result instanceof Object[]) {
				Arrays.sort((Object[]) result, adaptDependencyComparator(matchingBeans));//这里会进行排序
			}
			return result;
		}
		else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {
			Class<?> elementType = descriptor.getCollectionType();
			if (elementType == null) {
				return null;
			}
			Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType,
					new MultiElementDescriptor(descriptor));
			if (matchingBeans.isEmpty()) {
				return null;
			}
			if (autowiredBeanNames != null) {
				autowiredBeanNames.addAll(matchingBeans.keySet());
			}
			TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
			Object result = converter.convertIfNecessary(matchingBeans.values(), type);
			if (getDependencyComparator() != null && result instanceof List) {
				Collections.sort((List<?>) result, adaptDependencyComparator(matchingBeans));//这里会进行排序
			}
			return result;
		}
		else if (Map.class.isAssignableFrom(type) && type.isInterface()) {
			
		}
		else {
			return null;
		}
	}

comparator分析

OrderComparator的实现非常简单,按照compare--> doCompare --> getOrder(Object , OrderSourceProvider)--> getOrder(Object )-->findOrder() 循序查看就好了

输入图片说明

OrderComparator核心代码

public class OrderComparator implements Comparator<Object> {

	/**
	 * Shared default instance of {@code OrderComparator}.
	 */
	public static final OrderComparator INSTANCE = new OrderComparator();


	public Comparator<Object> withSourceProvider(final OrderSourceProvider sourceProvider) {
		return new Comparator<Object>() {
			@Override
			public int compare(Object o1, Object o2) {
				return doCompare(o1, o2, sourceProvider);
			}
		};
	}

	@Override
	public int compare(Object o1, Object o2) {
		return doCompare(o1, o2, null);
	}

	private int doCompare(Object o1, Object o2, OrderSourceProvider sourceProvider) {
		boolean p1 = (o1 instanceof PriorityOrdered);
		boolean p2 = (o2 instanceof PriorityOrdered);
		//  如果一个PriorityOrdered实现,一个是Ordered实现,PriorityOrdered实现优先Ordered实现
		if (p1 && !p2) {
			return -1;
		}
		else if (p2 && !p1) {
			return 1;
		}

		// 当两个对象都是PriorityOrdered或者Ordered,得到order值,进行比较
		int i1 = getOrder(o1, sourceProvider);
		int i2 = getOrder(o2, sourceProvider);
		return (i1 < i2) ? -1 : (i1 > i2) ? 1 : 0;
	}

	private int getOrder(Object obj, OrderSourceProvider sourceProvider) {
		Integer order = null;
		if (sourceProvider != null) {
			Object orderSource = sourceProvider.getOrderSource(obj);
			if (orderSource != null && orderSource.getClass().isArray()) {
				Object[] sources = ObjectUtils.toObjectArray(orderSource);
				for (Object source : sources) {
					order = findOrder(source);
					if (order != null) {
						break;
					}
				}
			}
			else {
				order = findOrder(orderSource);
			}
		}
		return (order != null ? order : getOrder(obj));
	}

	protected int getOrder(Object obj) {
		Integer order = findOrder(obj);// findOrder是核心,会被子类重写,
		return (order != null ? order : Ordered.LOWEST_PRECEDENCE);
	}
	/**
	 * 注意这个方法会被子类重写。主要是调用Ordered实现类 实现的getOrder方法,得到orderd值
	 **/
	protected Integer findOrder(Object obj) {
		return (obj instanceof Ordered ? ((Ordered) obj).getOrder() : null);
	}

 	/**
	 * 注意这个方法会被子类重写
	 **/
	public Integer getPriority(Object obj) {
		return null;
	}
}

AnnotationAwareOrderComparator核心代码

public class AnnotationAwareOrderComparator extends OrderComparator {

	public static final AnnotationAwareOrderComparator INSTANCE = new AnnotationAwareOrderComparator();

	protected Integer findOrder(Object obj) {
		// 调用OrderComparator.findOrder,先识别Ordered接口,
		Integer order = super.findOrder(obj);
		if (order != null) {
			return order;
		}

		// 检查@Order和@Priority各种元素
		// Method,AnnotatedElement的对象只会识别@Order
		if (obj instanceof Class) {
			return OrderUtils.getOrder((Class<?>) obj);
		}
		else if (obj instanceof Method) {
			Order ann = AnnotationUtils.findAnnotation((Method) obj, Order.class);
			if (ann != null) {
				return ann.value();
			}
		}
		else if (obj instanceof AnnotatedElement) {
			Order ann = AnnotationUtils.getAnnotation((AnnotatedElement) obj, Order.class);
			if (ann != null) {
				return ann.value();
			}
		}
		else if (obj != null) {
			order = OrderUtils.getOrder(obj.getClass());
			if (order == null && obj instanceof DecoratingProxy) {
				order = OrderUtils.getOrder(((DecoratingProxy) obj).getDecoratedClass());
			}
		}

		return order;
	}


	public Integer getPriority(Object obj) {
		Integer priority = null;
		if (obj instanceof Class) {
			priority = OrderUtils.getPriority((Class<?>) obj);
		}
		else if (obj != null) {
			priority = OrderUtils.getPriority(obj.getClass());
			if (priority == null && obj instanceof DecoratingProxy) {
				priority = OrderUtils.getOrder(((DecoratingProxy) obj).getDecoratedClass());
			}
		}
		return priority;
	}

}

OrderUtils

OrderUtils 很简单负责从class中识别 @Priority 与 @Order注解

public abstract class OrderUtils {

	private static Class<? extends Annotation> priorityAnnotationType = null;

	static {
		try {
			// 加载 @Priority 注解,
			priorityAnnotationType = (Class<? extends Annotation>)
					ClassUtils.forName("javax.annotation.Priority", OrderUtils.class.getClassLoader());
		}
		catch (Throwable ex) {
			// javax.annotation.Priority not available, or present but not loadable (on JDK 6)
		}
	}


	public static Integer getOrder(Class<?> type) {
		return getOrder(type, null);
	}

	
	public static Integer getOrder(Class<?> type, Integer defaultOrder) {
		// @Order 优于 @Priority 识别
		Order order = AnnotationUtils.findAnnotation(type, Order.class);
		if (order != null) {
			return order.value();
		}
		// 识别 @Priority 注释
		Integer priorityOrder = getPriority(type);
		if (priorityOrder != null) {
			return priorityOrder;
		}
		return defaultOrder;
	}

	
	public static Integer getPriority(Class<?> type) {
		if (priorityAnnotationType != null) {
			Annotation priority = AnnotationUtils.findAnnotation(type, priorityAnnotationType);
			if (priority != null) {
				return (Integer) AnnotationUtils.getValue(priority);
			}
		}
		return null;
	}

}

总结

Ordered相关对象总结

  1. 默认具有以下接口与注解的类才会进行排序
    1. PriorityOrdered
    2. Ordered
    3. @Order
    4. @Priority
  2. OrderComparator负责PriorityOrdered,Ordered
  3. AnnotationAwareOrderComparator负责@Order, @Priority
  4. AnnotationAwareOrderComparator只会在xml开启action扫描或者使用 AnnotatedBeanDefinitionReader与ClassPathBeanDefinitionScanner,才会加载

只会对同类型的对象进行排序

  1. 对BeanFactoryPostProcessor,及子类进行排序
  2. 在调用getBean,如果是返回结果是List或者是Array.就会进行排序
  3. ConfigurationClassParser.processDeferredImportSelectors 对@Impor排序
  4. AspectJ 也就是aop

识别优先级

同时存在多个排序实现方式,哪个方式的值作为排序的值。Ordered优选级比@Order,@Order优选级@Priority高

@Order(value = -10000)
@Priority ( value = 0 )
public class OrderType implements Ordered{

	@Override
	public int getOrder( ) {
		return 10000;
	}
}

上面的代码,如何通过AnnotationAwareOrderComparato.findOrde()得到的值是10000,如果没有实现Ordered接口,得到是值是-1000

排序优先级

	@Test
	public void orderTypeTest(){
		List<Ordered> list = new ArrayList< Ordered >();
		list.add( new OrderType( ) );
		list.add( new PriorityOrderedType() );
		
		Collections.sort(list , AnnotationAwareOrderComparator.INSTANCE);
		System.out.println( list );
	}
	
	public class OrderType implements Ordered{

		@Override
		public int getOrder( ) {
			return -1;
		}
		
		public String toString(){
			return "Ordered";
		}
	}
	
	
	public class PriorityOrderedType implements PriorityOrdered{

		@Override
		public int getOrder( ) {
			return 10000;
		}
		public String toString(){
			return "PriorityOrderedType";
		}
		
	}

[PriorityOrderedType, Ordered]

从上面的代码,与结果会发现,PriorityOrdered的实现类order值是10000,而Ordered的实现类order值是-10000,理论上来说输出结果是[Ordered , PriorityOrderedType],为什么出现这种情况。因为PriorityOrdered接口排序优选Ordered接口(包括@Order, @Priority)

Comparator.comparing排序使用示例

Comparator.comparing排序使用示例

Comparator.comparing排序使用示例

[TOC]

背景

以前常用的排序方式是通过实现Comparator接口来进行排序,写法相对来说比较复杂,使用Comparator.comparing可以简化代码,看起来逻辑更清晰。

实体类

import lombok.Data;

/**
 * @Author: ck
 * @Date: 2021/10/12 3:51 下午
 */
@Data
public class Model {
    private String name;
    private int age;
}

示例一

通过实现Comparator接口来进行排序,代码相对较复杂

Collections.sort(models, new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        return o1.compareTo(o2);
    }
});

示例二

使用Comparator.comparing实现排序,同样可以指定按照哪个属性排序,且可以实现倒序。

package com.kaesar.java_common;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * Comparator.comparing 方法的使用
 *
 * @Author: ck
 * @Date: 2021/10/12 3:51 下午
 */
public class ComparatorTest {
    public static void main(String[] args) {
        List<Model> models = new ArrayList<>();
        Model model1 = new Model();
        model1.setAge(300);
        model1.setName("a");
        models.add(model1);

        Model model2 = new Model();
        model2.setAge(500);
        model2.setName("c");
        models.add(model2);

        Model model3 = new Model();
        model3.setAge(100);
        model3.setName("b");
        models.add(model3);

        System.out.println("-----排序前-----");
        // 排序前
        for (Model contract : models) {
            System.out.println(contract.getName() + " " + contract.getAge());
        }

        System.out.println("-----排序后,根据age排序-----");
        Collections.sort(models, Comparator.comparing(Model::getAge));
        // 排序后
        for (Model model : models) {
            System.out.println(model.getName() + " " + model.getAge());
        }

        System.out.println("-----排序后,根据age排倒序-----");
        Collections.sort(models, Comparator.comparing(Model::getAge).reversed());
        // 排序后
        for (Model model : models) {
            System.out.println(model.getName() + " " + model.getAge());
        }

        System.out.println("-----排序后,根据name排序-----");
        Collections.sort(models, Comparator.comparing(Model::getName));
        // 排序后
        for (Model model : models) {
            System.out.println(model.getName() + " " + model.getAge());
        }
    }
}

$1.01^{365} ≈ 37.7834343329$
$0.99^{365} ≈ 0.02551796445$
相信坚持的力量!

FixedOrderComparator BeanComparator 实现指定排序

FixedOrderComparator BeanComparator 实现指定排序

实现根据指定的数组排序,切未指定的属性,在指定之前

String[] strs = { "北部网信","其他","合计","南部" };
        Arrays.sort(strs);
        log.info("-{}", JSONObject.toJSONString(strs));
        String[] sorts = { "其他","合计" };
        FixedOrderComparator<String> fixedOrderComparator = new FixedOrderComparator<String>(sorts);
        fixedOrderComparator.setUnknownObjectBehavior(FixedOrderComparator.UnknownObjectBehavior.BEFORE);
        Arrays.sort(strs, fixedOrderComparator);
        log.info("-{}", JSONObject.toJSONString(strs));
执行结果
2019-04-12 14:25:35 [main] INFO  FixedOrderComparatorTest:29 - -["其他","北部网信","南部","合计"]
2019-04-12 14:25:35 [main] INFO  FixedOrderComparatorTest:34 - -["北部网信","南部","其他","合计"]

实现java bean 中属性排序

    String[] sorts = { "其他","合计" };

        List<Team> teams = new ArrayList<>();
        Team team = new Team();
        team.setName("北部网信");
        teams.add(team);
        Team team1 = new Team();
        team1.setName("其他");
        teams.add(team1);
        Team team2 = new Team();
        team2.setName("合计");
        teams.add(team2);
        Team team3 = new Team();
        team3.setName("南部");
        teams.add(team3);
        FixedOrderComparator<String> fixedOrderComparator = new FixedOrderComparator<String>(sorts);
        		fixedOrderComparator.setUnknownObjectBehavior(FixedOrderComparator.UnknownObjectBehavior.BEFORE);
        BeanComparator beanComparator = new BeanComparator("name",fixedOrderComparator);
        Collections.sort(teams, beanComparator);
        log.info("-{}", JSONObject.toJSONString(teams));
执行结果:
[{"name":"北部网信"},{"name":"南部"},{"name":"其他"},{"name":"合计"}]

Java Comparator comparingInt() 的使用

Java Comparator comparingInt() 的使用

comparingInt

  • comparingInt
    • 自定义排序参数
    • 优先队列,重写比较器
  • 后序

comparingInt

static <T> Comparator<T> comparingInt​(ToIntFunction<? super T> keyExtractor)
接受提取的一个函数int从类型分类键T ,并返回一个Comparator ,通过该排序关键字进行比较。
如果指定的功能也可串行化,则返回的比较器是可序列化的。 (摘自API)

  • 参数类型
    T - 要比较的元素的类型

  • 参数
    keyExtractor - 用于提取整数排序键的函数

  • 结果
    比较器,其被提取的密钥进行比较

  • 异常
    NullPointerException - 如果参数为空

API Note:
例如,要获得一个Comparator ,它比较了Person对象的姓氏,

> Comparator<Person> byLastName = Comparator.comparing(Person::getLastName);

自定义排序参数

import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

// 重写比较器
class Persons implements  Comparable<Persons> {
    String name;
    int age;

    public Persons(String name, int age) {
        this.name = name;
        this.age = age;
    }
	
	// 定义此方法接受单个参数keyExtractor,该参数是用于提取整数排序键的函数。
    public int getAge() {
        return this.age;
    }

    // 按姓氏ASCII降序,反过来升序
    @Override
    public int compareto(Persons o) {
        return this.name.compareto(o.name);
    }
}

public class ComparatorTest {
    public static void main(String[] args) {
        // create some Persons objects
        Persons p1 = new Persons("B", 10);
        Persons p2 = new Persons("D", 20);
        Persons p3 = new Persons("A", 18);

        // before sort
        List<Persons> list = Arrays.asList(p2, p1, p3);
        System.out.println("Before Sort:");
        list.forEach(Persons -> System.out.println("Persons name"+Persons.name));

        // 自定义比较器
        Comparator<Persons> byAge = Comparator.comparingInt(Persons::getAge);
        Collections.sort(list, byAge);
        System.out.println("After Sort:");
        list.forEach(Persons -> System.out.println("Persons age"+Persons.age));
    }
}

结果

Before Name Sort:
Persons nameD
Persons nameB
Persons nameA

After Age Sort:
Persons nameB
Persons nameA
Persons nameD

优先队列,重写比较器

 // 定义优先队列,修改默认升序的排序关键字 key
PriorityQueue<int[]> minHeap = new PriorityQueue<>(Comparator.comparingInt(a -> a[1]));

后序

请参考:Java Arrays.asList() 的避雷

请参考:Java中 forEach() 和 Iterator 与 增强for循环 的那些事儿

参考大佬文章,及官方API,向优秀的人致敬!

加油!

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

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

这篇文章主要介绍了 Java Comparator.comparing 比较导致空指针异常的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
 

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

1
Comparator.comparing(Department::getOrder)

原因:

1
2
3
4
5
6
7
public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
         Function<? super T, ? extends U> keyExtractor)
{
     Objects.requireNonNull(keyExtractor);
     return (Comparator<T> & Serializable)
         (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
}

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

替代方案

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

替代方案好处:

1
2
3
4
5
6
7
8
9
10
public static <T, U> Comparator<T> comparing(
         Function<? super T, ? extends U> keyExtractor,
         Comparator<? super U> keyComparator)
{
     Objects.requireNonNull(keyExtractor);
     Objects.requireNonNull(keyComparator);
     return (Comparator<T> & Serializable)
         (c1, c2) -> keyComparator.compare(keyExtractor.apply(c1),
                                           keyExtractor.apply(c2));
}

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

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

1
2
3
public static <T> Comparator<T> nullsFirst(Comparator<? super T> comparator) {
     return new Comparators.NullComparator<>( true , comparator);
}

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/**
  * Null-friendly comparators
  */
final static class NullComparator<T> implements Comparator<T>, Serializable {
     private static final long serialVersionUID = -7569533591570686392L;
     private final boolean nullFirst;
     // if null, non-null Ts are considered equal
     private final Comparator<T> real;
     @SuppressWarnings ( "unchecked" )
     NullComparator( boolean nullFirst, Comparator<? super T> real) {
         this .nullFirst = nullFirst;
         this .real = (Comparator<T>) 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<T> thenComparing(Comparator<? super T> other) {
         Objects.requireNonNull(other);
         return new NullComparator<>(nullFirst, real == null ? other : real.thenComparing(other));
     }
     @Override
     public Comparator<T> reversed() {
         return new NullComparator<>(!nullFirst, real == null ? null : real.reversed());
     }
}

Comparator 中 comparing 方法的学习

例子:

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

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

1
2
3
4
5
public class Obj {
     private String name;
     private BigDecimal price;
     ......
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
@Test
     public void sort() {
         List<Obj> 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<String> sortList =  Arrays.asList( "PPD" , "政府" , "合作" );
         List<Obj> result = list.stream().sorted(
                 //先按照name排序(模拟需求的a属性排序)
                 Comparator.comparing(Obj::getName,(x,y)-> {
                     if (x == null && y != null ){
                         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 if (sort.equals(x)){
                                 return - 1 ;
                             } else {
                                 return 1 ;
                             }
                         }
                     }
                     return 0 ;
                     }
                 })).collect(Collectors.toList());
         System.out.println(result);
     }

1. 实现

comparing 方法有两种实现

方法 1: 只有一个参数,参数的类型是一个函数式接口 在这里插入图片描述

方法 2:

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

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

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

在这里插入图片描述

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

comparing

今天的关于第二章 一节spring-core之comparator深入解读spring-core详解的分享已经结束,谢谢您的关注,如果想了解更多关于Comparator.comparing排序使用示例、FixedOrderComparator BeanComparator 实现指定排序、Java Comparator comparingInt() 的使用、Java Comparator.comparing 比较导致空指针异常的解决的相关知识,请在本站进行查询。

本文标签: