当前位置: 首页 > news >正文

03 Strategy策略

抽丝剥茧设计模式 之 Strategy策略 - 更多内容请见 目录

文章目录

  • 一、Strategy策略
  • 二、Comparable和Comparator源码分析
    • 使用案例
    • Arrays.sort源码
    • Collections.sort源码
    • Comparable源码
    • Comparator源码


一、Strategy策略

策略模式是一种设计模式,它定义了一系列的算法,并将每个算法封装起来,使它们可以互相替换。Java中的Comparable和Comparator两个接口确实是策略模式的典型应用。

在Go语言的基本类库中,也有一些接口和实现是基于策略模式的。例如,io.Reader和io.Writer就是这样的接口。这两个接口定义了读取和写入数据的通用方法,但具体的实现可以根据不同的需求进行替换。你可以使用内存中的字节切片作为数据源,也可以使用文件、网络连接或其他任何数据源作为数据源,只要实现io.Reader和io.Writer接口即可。

另一个例子是http.Handler接口,它定义了处理HTTP请求的方法。你可以编写自己的实现该接口的函数,然后将其注册到HTTP服务器上,以处理特定的URL路径或路由。

这些例子中,接口定义了一组通用的方法,而具体的实现可以根据不同的需求进行替换。这种模式使得代码更加灵活,易于扩展和维护,符合策略模式的思想。

二、Comparable和Comparator源码分析

以下代码分析,基于openjdk-jdk8-b120,我们可以注意到,我们自定义了一个Comparator的子类,用于封装一组可以对对象进行比较的算法。传给sort()方法作为参数,用于决定排序的实际策略。

使用案例

首先看两个使用案例,Arrays.sort和Collections.sort都可以接收一个自定义的Comparator,用于对数组排序。

// Arrays.sort
import java.util.Arrays;
import java.util.Comparator;public class Main {public static void main(String[] args) {Integer[] numbers = {3, 1, 2, 4};// 使用自定义的Comparator对数组进行排序Comparator<Integer> comparator = new MyComparator();Arrays.sort(numbers, comparator);System.out.println(Arrays.toString(numbers)); // 输出: [1, 2, 3, 4]}static class MyComparator implements Comparator<Integer> {@Overridepublic int compare(Integer o1, Integer o2) {return o1.compareTo(o2);}}
}
// Collections.sort
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;public class Main {public static void main(String[] args) {List<String> names = new ArrayList<>();names.add("Alice");names.add("Bob");names.add("Charlie");// 使用自定义的比较器对列表进行排序Comparator<String> comparator = new LengthComparator();Collections.sort(names, comparator);System.out.println(names); // 输出: [Charlie, Bob, Alice]}static class LengthComparator implements Comparator<String> {@Overridepublic int compare(String o1, String o2) {return Integer.compare(o1.length(), o2.length());}}
}

Arrays.sort源码

package java.util;public class Arrays {private Arrays() {}public static <T> void sort(T[] a, Comparator<? super T> c) {if (c == null)c = NaturalOrder.INSTANCE;if (LegacyMergeSort.userRequested)legacyMergeSort(a, c);elseTimSort.sort(a, 0, a.length, c, null, 0, 0);}
}

Collections.sort源码

package java.util;
public class Collections {// Suppresses default constructor, ensuring non-instantiability.private Collections() {}@SuppressWarnings({"unchecked", "rawtypes"})public static <T> void sort(List<T> list, Comparator<? super T> c) {Object[] a = list.toArray();Arrays.sort(a, (Comparator)c);ListIterator<T> i = list.listIterator();for (int j=0; j<a.length; j++) {i.next();i.set((T)a[j]);}}
}

Comparable源码

package java.lang;
import java.util.*;
public interface Comparable<T> {public int compareTo(T o);
}

Comparator源码

package java.util;import java.io.Serializable;
import java.util.function.Function;
import java.util.function.ToIntFunction;
import java.util.function.ToLongFunction;
import java.util.function.ToDoubleFunction;
import java.util.Comparators;@FunctionalInterface
public interface Comparator<T> {int compare(T o1, T o2);boolean equals(Object obj);default Comparator<T> reversed() {return Collections.reverseOrder(this);}default Comparator<T> thenComparing(Comparator<? super T> other) {Objects.requireNonNull(other);return (Comparator<T> & Serializable) (c1, c2) -> {int res = compare(c1, c2);return (res != 0) ? res : other.compare(c1, c2);};}default <U extends Comparable<? super U>> Comparator<T> thenComparing(Function<? super T, ? extends U> keyExtractor,Comparator<? super U> keyComparator){return thenComparing(comparing(keyExtractor, keyComparator));}default <U extends Comparable<? super U>> Comparator<T> thenComparing(Function<? super T, ? extends U> keyExtractor){return thenComparing(comparing(keyExtractor));}default Comparator<T> thenComparingInt(ToIntFunction<? super T> keyExtractor) {return thenComparing(comparingInt(keyExtractor));}default Comparator<T> thenComparingLong(ToLongFunction<? super T> keyExtractor) {return thenComparing(comparingLong(keyExtractor));}default Comparator<T> thenComparingDouble(ToDoubleFunction<? super T> keyExtractor) {return thenComparing(comparingDouble(keyExtractor));}public static <T extends Comparable<? super T>> Comparator<T> reverseOrder() {return Collections.reverseOrder();}@SuppressWarnings("unchecked")public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() {return (Comparator<T>) Comparators.NaturalOrderComparator.INSTANCE;}public static <T> Comparator<T> nullsFirst(Comparator<? super T> comparator) {return new Comparators.NullComparator<>(true, comparator);}public static <T> Comparator<T> nullsLast(Comparator<? super T> comparator) {return new Comparators.NullComparator<>(false, comparator);}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));}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));}public static <T> Comparator<T> comparingInt(ToIntFunction<? super T> keyExtractor) {Objects.requireNonNull(keyExtractor);return (Comparator<T> & Serializable)(c1, c2) -> Integer.compare(keyExtractor.applyAsInt(c1), keyExtractor.applyAsInt(c2));}public static <T> Comparator<T> comparingLong(ToLongFunction<? super T> keyExtractor) {Objects.requireNonNull(keyExtractor);return (Comparator<T> & Serializable)(c1, c2) -> Long.compare(keyExtractor.applyAsLong(c1), keyExtractor.applyAsLong(c2));}public static<T> Comparator<T> comparingDouble(ToDoubleFunction<? super T> keyExtractor) {Objects.requireNonNull(keyExtractor);return (Comparator<T> & Serializable)(c1, c2) -> Double.compare(keyExtractor.applyAsDouble(c1), keyExtractor.applyAsDouble(c2));}
}

相关文章:

03 Strategy策略

抽丝剥茧设计模式 之 Strategy策略 - 更多内容请见 目录 文章目录 一、Strategy策略二、Comparable和Comparator源码分析使用案例Arrays.sort源码Collections.sort源码Comparable源码Comparator源码 一、Strategy策略 策略模式是一种设计模式&#xff0c;它定义了一系列的算法…...

Python实现分位数回归模型(quantreg算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 分位数回归是简单的回归&#xff0c;就像普通的最小二乘法一样&#xff0c;但不是最小化平方误差的总和…...

【ROS2简单例程】基于python的发布订阅实现

1、自定义消息类型Student 1.1 创建base_interfaces_demo包 1.2 创建Student.msg文件 string name int32 age float64 height 1.2 在cmakeLists.txt中增加如下语句 #增加自定义消息类型的依赖 find_package(rosidl_default_generators REQUIRED) # 为接口文件生成源代码 ro…...

【期末考试】数据库综合复习宝典

目录 第一章 数据库系统概述 第二章 关系代数 第四章 关系数据库理论 第五章 数据库设计 第六章 数据库管理系统 第八章 事务管理 第一章 数据库系统概述 1.1三级模式 ①外模式&#xff1a;它为特定的应用程序或用户群体提供了一个数据视图&#xff0c;这个视图是独立于…...

OpenHarmony南向之LCD显示屏

OpenHarmony南向之LCD显示屏 概述 LCD&#xff08;Liquid Crystal Display&#xff09;驱动&#xff0c;通过对显示器上下电、初始化显示器驱动IC&#xff08;Integrated Circuit&#xff09;内部寄存器等操作&#xff0c;使其可以正常工作。 HDF Display驱动模型 LCD器件驱…...

核心笔记-短篇

接口管理平台:yapi 对象拷贝:Spring Bean 提供的 BeanUtils;hutool-core 提供的 BeanUtil 获得用户设备的信息:导入 UserAgentUtils 依赖;创建 UserAgent 对象使用 加密工具:DigestUtils,Spring Core 提供,静态方法:md5DigestAsHex(byte[]) 客户端编程工具包:HttpCli…...

系统学习Python——警告信息的控制模块warnings:为新版本的依赖关系更新代码

分类目录&#xff1a;《系统学习Python》总目录 在默认情况下&#xff0c;主要针对Python开发者&#xff08;而不是Python应用程序的最终用户&#xff09;的警告类别&#xff0c;会被忽略。 值得注意的是&#xff0c;这个“默认忽略”的列表包含DeprecationWarning&#xff08…...

爬虫的基本原理

基本原理 可以把网页与网页之间的链接关系比作节点中的连线&#xff0c;爬虫可以根据网页中的关系获取后续的网页&#xff0c;当整个网站涉及的页面全部被爬虫访问到后&#xff0c;网站的数据就被访问下来了。 1.爬虫概述 简单点讲&#xff0c;爬虫就是获取网页并提取和保存信…...

MySQL核心SQL

一.结构化查询语言 SQL是结构化查询语言&#xff08;Structure Query Language&#xff09;&#xff0c;它是关系型数据库的通用语言。 SQL 主要可以划分为以下 3 个类别&#xff1a; DDL&#xff08;Data Definition Languages&#xff09;语句 数据定义语言&#xff0c;这…...

关于 setData 同步异步的问题

小程序官方文档中的回答解释: 所以大概意思就是: 1.setData在逻辑层的操作是同步&#xff0c;因此this.data中的相关数据会立即更新,比如下面的例子: const a 1 this.setData({b: a ? a : , }) console.log(that.data.b) // 1 2. setData在视图层的操作是异步&#xff0c;…...

Centos创建一个Python虚拟环境

在 CentOS 上创建一个 Python 虚拟环境&#xff0c;可以使用 virtualenv 工具。以下是创建和激活虚拟环境的基本步骤&#xff1a; 1.安装virtualenv 如果还没有安装 virtualenv&#xff0c;可以使用以下命令安装&#xff1a; sudo yum install python3-virtualenv请注意&…...

怎么使用好爬虫IP代理?爬虫代理IP有哪些使用技巧?

在互联网时代&#xff0c;爬虫技术被广泛应用于数据采集和处理。然而&#xff0c;在使用爬虫技术的过程中&#xff0c;经常会遇到IP被封禁的问题&#xff0c;这给数据采集工作带来了很大的困扰。因此&#xff0c;使用爬虫IP代理成为了解决这个问题的有效方法。本文将介绍如何使…...

C#,字符串匹配算法(模式搜索)Z算法的源代码与数据可视化

Z算法也是模式搜索&#xff08;Pattern Search Algorithm&#xff09;的常用算法。 本文代码的运算效果&#xff1a; 一、Z 算法 线性时间模式搜索算法的Z算法&#xff0c;在线性时间内查找文本中模式的所有出现。 假设文本长度为 n&#xff0c;模式长度为 m&#xff0c;那么…...

强化学习actor-critic

...

使用推测解码 (Speculative Decoding) 使 Whisper 实现 2 倍的推理加速

Open AI 推出的 Whisper 是一个通用语音转录模型&#xff0c;在各种基准和音频条件下都取得了非常棒的结果。最新的 large-v3 模型登顶了 OpenASR 排行榜&#xff0c;被评为最佳的开源英语语音转录模型。该模型在 Common Voice 15 数据集的 58 种语言中也展现出了强大的多语言性…...

pi gpio 内存映射

树霉pi gpio内存映射 #include <stdio.h> #include <fcntl.h> #include <sys/mman.h> #include <unistd.h> #include <stdlib.h>#define BCM2835_PERI_BASE 0x20000000 #define GPIO_BASE (BCM2835_PERI_BASE 0x200000) #define PAGE_SIZE…...

[NAND Flash 6.2] NAND 初始化常用命令:复位 (Reset) 和 Read ID 和 Read UID 操作和代码实现

依公知及经验整理,原创保护,禁止转载。 专栏 《深入理解NAND Flash》 <<<< 返回总目录 <<<< 把下文中的字母和数字用`包起来, 中文不变。 全文 4400 字,主要内容 复位的目的和作用? NAND Reset 种类:FFh, FCh, FAh, FDh 区别 Reset 操作步骤 和…...

Multimodal Prototypical Networks for Few-shot Learning

tcGAN is provided with an embedding ϕ T \phi_T ϕT​() of the textual description 辅助信息 作者未提供代码...

软件测试|Python requests库的安装和使用指南

简介 requests库是Python中一款流行的HTTP请求库&#xff0c;用于简化HTTP请求的发送和处理&#xff0c;也是我们在使用Python做接口自动化测试时&#xff0c;最常用的第三方库。本文将介绍如何安装和使用requests库&#xff0c;以及一些常见的用例示例。 安装requests库 首…...

HarmonyOS应用开发学习笔记 应用上下文Context 获取文件夹路径

1、 HarmoryOS Ability页面的生命周期 2、 Component自定义组件 3、HarmonyOS 应用开发学习笔记 ets组件生命周期 4、HarmonyOS 应用开发学习笔记 ets组件样式定义 Styles装饰器&#xff1a;定义组件重用样式 Extend装饰器&#xff1a;定义扩展组件样式 5、HarmonyOS 应用开发…...

Cursor实现用excel数据填充word模版的方法

cursor主页&#xff1a;https://www.cursor.com/ 任务目标&#xff1a;把excel格式的数据里的单元格&#xff0c;按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例&#xff0c;…...

iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘

美国西海岸的夏天&#xff0c;再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至&#xff0c;这不仅是开发者的盛宴&#xff0c;更是全球数亿苹果用户翘首以盼的科技春晚。今年&#xff0c;苹果依旧为我们带来了全家桶式的系统更新&#xff0c;包括 iOS 26、iPadOS 26…...

利用ngx_stream_return_module构建简易 TCP/UDP 响应网关

一、模块概述 ngx_stream_return_module 提供了一个极简的指令&#xff1a; return <value>;在收到客户端连接后&#xff0c;立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量&#xff08;如 $time_iso8601、$remote_addr 等&#xff09;&a…...

【JVM】- 内存结构

引言 JVM&#xff1a;Java Virtual Machine 定义&#xff1a;Java虚拟机&#xff0c;Java二进制字节码的运行环境好处&#xff1a; 一次编写&#xff0c;到处运行自动内存管理&#xff0c;垃圾回收的功能数组下标越界检查&#xff08;会抛异常&#xff0c;不会覆盖到其他代码…...

HTML 列表、表格、表单

1 列表标签 作用&#xff1a;布局内容排列整齐的区域 列表分类&#xff1a;无序列表、有序列表、定义列表。 例如&#xff1a; 1.1 无序列表 标签&#xff1a;ul 嵌套 li&#xff0c;ul是无序列表&#xff0c;li是列表条目。 注意事项&#xff1a; ul 标签里面只能包裹 li…...

渲染学进阶内容——模型

最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

uniapp中使用aixos 报错

问题&#xff1a; 在uniapp中使用aixos&#xff0c;运行后报如下错误&#xff1a; AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...

OPENCV形态学基础之二腐蚀

一.腐蚀的原理 (图1) 数学表达式&#xff1a;dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一&#xff0c;腐蚀跟膨胀属于反向操作&#xff0c;膨胀是把图像图像变大&#xff0c;而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...

HarmonyOS运动开发:如何用mpchart绘制运动配速图表

##鸿蒙核心技术##运动开发##Sensor Service Kit&#xff08;传感器服务&#xff09;# 前言 在运动类应用中&#xff0c;运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据&#xff0c;如配速、距离、卡路里消耗等&#xff0c;用户可以更清晰…...