【小家Java】聊聊Java中的比较器(排序):Comparable和Comparator;Spring中的Comparators和AnnotationAwareOrderComparator(下)

简介: 【小家Java】聊聊Java中的比较器(排序):Comparable和Comparator;Spring中的Comparators和AnnotationAwareOrderComparator(下)

Spring中的ComparableComparator和Comparators


备注此处的Comparators指的是Spring包下的:org.springframework.util.comparator.Comparators,因为JDK自带的java.util.Comparators它是不提供给外部访问的。


ComparableComparator

// @since 1.2.2 比较器,用于将可比较器适配比较器接口。
public class ComparableComparator<T extends Comparable<T>> implements Comparator<T> {
  // 实例 单例    这样子的话就可以当作Comparator来使用了
  @SuppressWarnings("rawtypes")
  public static final ComparableComparator INSTANCE = new ComparableComparator();
  @Override
  public int compare(T o1, T o2) {
    return o1.compareTo(o2);
  }
}


这个适配类是Spring1.2.2就出来了,但是下面的工具:Comparators可是Spring5.0才提供


Comparators


它是Spring5.0后提供的一个工具类,里面主要是提供了一些静态方法,来提供外部比较器

// @since 5.0  注意使用它和直接使用Comparator的区别是,它要求你比较的对象都实现了Comparable的   否则都是不适用的
public abstract class Comparators {
  // 自然排序~~~~
  // Arrays.sort(people, Comparators.comparable()); 比如你这么用,是要求peple里面元素实现了Comparable接口的  否则报错
  @SuppressWarnings("unchecked")
  public static <T> Comparator<T> comparable() {
    return ComparableComparator.INSTANCE;
  }
  // null放在最后
  @SuppressWarnings("unchecked")
  public static <T> Comparator<T> nullsLow() {
    return NullSafeComparator.NULLS_LOW;
  }
  /// null放最后  并且我们还可以提供一个自定义的比较器
  public static <T> Comparator<T> nullsLow(Comparator<T> comparator) {
    return new NullSafeComparator<>(comparator, true);
  }
  @SuppressWarnings("unchecked")
  public static <T> Comparator<T> nullsHigh() {
    return NullSafeComparator.NULLS_HIGH;
  }
  public static <T> Comparator<T> nullsHigh(Comparator<T> comparator) {
    return new NullSafeComparator<>(comparator, false);
  }
}


OrderComparator


使用OrderComparator来比较2个对象的排序顺序。注意它用于Spring用来比较实现了Ordered接口的对象。

注意它@since 07.04.2003出现得非常早,所以这个类并不支持@Order注解的排序~~~


但是,PriorityOrdered接口它也是支持的,虽然它Spring2.5才出现。

另外,它是一个Comparator,所以它可以作为自定义比较器放在数组、集合里排序。形如;

public class OrderComparator implements Comparator<Object> {
  ...
  public static void sort(List<?> list) {
    if (list.size() > 1) {
      list.sort(INSTANCE);
    }
  }
  public static void sort(Object[] array) {
    if (array.length > 1) {
      Arrays.sort(array, INSTANCE);
    }
  }
  public static void sortIfNecessary(Object value) {
    if (value instanceof Object[]) {
      sort((Object[]) value);
    }
    else if (value instanceof List) {
      sort((List<?>) value);
    }
  }
}


AnnotationAwareOrderComparator


AnnotationAwareOrderComparator继承自OrderComparator

其可以同时处理对象实现Ordered接口或@Order注解。


显然它增强了排序能力,不仅支持Ordered接口,还支持到了@Order注解。


@Order注解@since 2.0,AnnotationAwareOrderComparator它@since 2.0.1,几乎同时出现的


它提供了两个静态方法,使用非常广泛,方便我们对数组、即可记性排序:


public class AnnotationAwareOrderComparator extends OrderComparator {
  /**
   * 用来检查实现Ordered接口、@Order和@Priority注解
   */
    protected Integer findOrder(Object obj) {
    // 检查常规的Ordered接口,通过子类重写的getOrder方法返回顺序值
        Integer order = super.findOrder(obj);
    if (order != null) {
      return order;
    }
    // 检查实现@Order和@Priority注解
    if (obj instanceof Class) {
            // 在类上检查@Order和@Priority注解,并找出顺序值
      return OrderUtils.getOrder((Class<?>) obj);
    } else if (obj instanceof Method) {
            // 在方法上检查@Order注解,并找出顺序值
      Order ann = AnnotationUtils.findAnnotation((Method) obj, Order.class);
      if (ann != null) {
        return ann.value();
      }
    } else if (obj instanceof AnnotatedElement) {
            // 在注解中找@Order注解,并找出顺序值
      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;
  }
  // ==================================================================
  // 注意此处和上面的区别,它用的是自己的instance
  public static void sort(List<?> list) {
    if (list.size() > 1) {
      list.sort(INSTANCE);
    }
  }
   */
  public static void sort(Object[] array) {
    if (array.length > 1) {
      Arrays.sort(array, INSTANCE);
    }
  }
  public static void sortIfNecessary(Object value) {
    if (value instanceof Object[]) {
      sort((Object[]) value);
    }
    else if (value instanceof List) {
      sort((List<?>) value);
    }
  }
}


OrderUtils


最后介绍这个工具类,它是Spring4.1后提出的。它支持注解@Order和javax.annotation.Priority也是被支持的,因此它的getOrder()方法就是获取order值了。


需要注意的是:先找@Order,若没有再去找@Priority,都没标注就返回默认值

该工具类并不支持Ordered接口的方式~~~

总结


对象排序或许是平时我们开发中都忽略的一块小知识点,我本人而言,每次使用都需要自己单元测试一番,生怕顺序弄反了。因此对此部分内容作一个记录,希望成为永久的记忆~~~

相关文章
|
25天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
64 2
|
12天前
|
Java 开发者 微服务
Spring Boot 入门:简化 Java Web 开发的强大工具
Spring Boot 是一个开源的 Java 基础框架,用于创建独立、生产级别的基于Spring框架的应用程序。它旨在简化Spring应用的初始搭建以及开发过程。
28 6
Spring Boot 入门:简化 Java Web 开发的强大工具
|
1月前
|
人工智能 前端开发 Java
基于开源框架Spring AI Alibaba快速构建Java应用
本文旨在帮助开发者快速掌握并应用 Spring AI Alibaba,提升基于 Java 的大模型应用开发效率和安全性。
基于开源框架Spring AI Alibaba快速构建Java应用
|
2月前
|
前端开发 Java 数据库连接
Spring 框架:Java 开发者的春天
Spring 框架是一个功能强大的开源框架,主要用于简化 Java 企业级应用的开发,由被称为“Spring 之父”的 Rod Johnson 于 2002 年提出并创立,并由Pivotal团队维护。
66 1
Spring 框架:Java 开发者的春天
|
2月前
|
Java 数据库连接 开发者
Spring 框架:Java 开发者的春天
【10月更文挑战第27天】Spring 框架由 Rod Johnson 在 2002 年创建,旨在解决 Java 企业级开发中的复杂性问题。它通过控制反转(IOC)和面向切面的编程(AOP)等核心机制,提供了轻量级的容器和丰富的功能,支持 Web 开发、数据访问等领域,显著提高了开发效率和应用的可维护性。Spring 拥有强大的社区支持和丰富的生态系统,是 Java 开发不可或缺的工具。
|
2月前
|
JSON Java Maven
实现Java Spring Boot FCM推送教程
本指南介绍了如何在Spring Boot项目中集成Firebase云消息服务(FCM),包括创建项目、添加依赖、配置服务账户密钥、编写推送服务类以及发送消息等步骤,帮助开发者快速实现推送通知功能。
95 2
|
23天前
|
Java 数据库连接 API
Spring 框架的介绍(Java EE 学习笔记02)
Spring是一个由Rod Johnson开发的轻量级Java SE/EE一站式开源框架,旨在解决Java EE应用中的多种问题。它采用非侵入式设计,通过IoC和AOP技术简化了Java应用的开发流程,降低了组件间的耦合度,支持事务管理和多种框架的无缝集成,极大提升了开发效率和代码质量。Spring 5引入了响应式编程等新特性,进一步增强了框架的功能性和灵活性。
41 0
|
2月前
|
存储 人工智能 Java
将 Spring AI 与 LLM 结合使用以生成 Java 测试
AIDocumentLibraryChat 项目通过 GitHub URL 为指定的 Java 类生成测试代码,支持 granite-code 和 deepseek-coder-v2 模型。项目包括控制器、服务和配置,能处理源代码解析、依赖加载及测试代码生成,旨在评估 LLM 对开发测试的支持能力。
48 1
|
2月前
|
Java BI 调度
Java Spring的定时任务的配置和使用
遵循上述步骤,你就可以在Spring应用中轻松地配置和使用定时任务,满足各种定时处理需求。
154 1
|
1月前
|
安全 Java 测试技术
Java开发必读,谈谈对Spring IOC与AOP的理解
Spring的IOC和AOP机制通过依赖注入和横切关注点的分离,大大提高了代码的模块化和可维护性。IOC使得对象的创建和管理变得灵活可控,降低了对象之间的耦合度;AOP则通过动态代理机制实现了横切关注点的集中管理,减少了重复代码。理解和掌握这两个核心概念,是高效使用Spring框架的关键。希望本文对你深入理解Spring的IOC和AOP有所帮助。
35 0