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

Java特性之设计模式【过滤器模式】

一、过滤器模式

概述

​ 过滤器模式(Filter Pattern)或标准模式(Criteria Pattern)是一种设计模式,这种模式允许开发人员使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来。这种类型的设计模式属于结构型模式,它结合多个标准来获得单一标准

主要解决:在众多数据中,根据特定的标准,在一组数据中筛选出不同标准的数据

优缺点

优点:

  • 将对象的过滤、校验逻辑抽离出来,降低系统的复杂度
  • 过滤规则可实现重复利用

缺点:

  • 性能较低,每个过滤器对每一个元素都会进行遍历。如果有n个元素,m个过滤器,则时间复杂度为O(mn)

1. 各个角色介绍

1.1 过滤器接口(Filter)

  • 定义了过滤器的基本方法,具体的实现还要具体过滤器角色去参与,在实际应用中可以扩展该接口以适应不同的过滤条件

1.2 具体命过滤器(ConcreteFilter)

  • 实现了过滤器接口,负责执行具体的过滤操作。对数据进行过滤

1.3 过滤链(FilterChain)

  • 将多个过滤器按照一定的顺序组合起来,形成一个过滤器链,依次对数据进行过滤

2. UML图

​ 首先创建一个 Shape 对象,作为过滤的接口 IFilter,然后实现该接口,创建对应的 CornerFilterCurveFilterEdgeFilter具体过滤器。然后创建带有过滤器的过滤链 FilterChain,基于各种标准和它们的结合来过滤 Shape 对象的列表

在这里插入图片描述

3. 具体例子和代码

角色分配

  • Shape:形状
  • IFilter:过滤器接口
    • CornerFilter:角过滤器(实现过滤器接口)
    • EdgeFilter:边过滤器(实现过滤器接口)
    • CurveFilter:曲线过滤器(实现过滤器接口)
  • FilterChain:过滤链

3.1 形状

  • Instruction
package com.vinjcent.prototype.filter;import io.swagger.annotations.ApiModelProperty;/*** @author vinjcent* @description 形状*/
public class Shape {@ApiModelProperty("形状名称")private String name;@ApiModelProperty("是否有角")private Boolean isCorner;@ApiModelProperty("边数")private Integer edges;@ApiModelProperty("线构成类型")private String type;public Shape(String name, Boolean isCorner, Integer edges, String type) {this.name = name;this.isCorner = isCorner;this.edges = edges;this.type = type;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Boolean getCorner() {return isCorner;}public void setCorner(Boolean corner) {isCorner = corner;}public Integer getEdges() {return edges;}public void setEdges(Integer edges) {this.edges = edges;}public String getType() {return type;}public void setType(String type) {this.type = type;}
}

3.2 过滤接口及其实现类

  • IFilter
package com.vinjcent.prototype.filter;import java.util.List;/*** @author vinjcent* @description 过滤接口*/
public interface IFilter {/*** 适配标准形状** @param shapes 形状列表* @return 适配的形状列表*/List<Shape> adaptFilter(List<Shape> shapes);
}
  • CornerFilter
package com.vinjcent.prototype.filter;import java.util.ArrayList;
import java.util.List;/*** @author vinjcent* /* @description 角过滤器*/
public class CornerFilter implements IFilter {@Overridepublic List<Shape> adaptFilter(List<Shape> shapes) {// 符合具有角的形状List<Shape> cornerFilter = new ArrayList<>();for (Shape shape : shapes) {if (shape.getIsCorner()) {cornerFilter.add(shape);}}return cornerFilter;}}
  • EdgeFilter
package com.vinjcent.prototype.filter;import java.util.ArrayList;
import java.util.List;/*** @author vinjcent* /* @description 边过滤器*/
public class EdgeFilter implements IFilter {@Overridepublic List<Shape> adaptFilter(List<Shape> shapes) {// 边数大于0的形状List<Shape> edgeFilter = new ArrayList<>();for (Shape shape : shapes) {if (shape.getEdges() > 0) {edgeFilter.add(shape);}}return edgeFilter;}}
  • CurveFilter
package com.vinjcent.prototype.filter;import java.util.ArrayList;
import java.util.List;/*** @author vinjcent* /* @description 曲线过滤器*/
public class CurveFilter implements IFilter {@Overridepublic List<Shape> adaptFilter(List<Shape> shapes) {// 曲线List<Shape> curveFilter = new ArrayList<>();for (Shape shape : shapes) {if (shape.getType().toLowerCase().contains("curve")) {curveFilter.add(shape);}}return curveFilter;}}

3.3 过滤链

  • FilterChain
package com.vinjcent.prototype.filter;import com.vinjcent.api.utils.CollectionUtils;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;import java.util.ArrayList;
import java.util.List;/*** @author vinjcent* @description 过滤链*/
@Data
public class FilterChain {@ApiModelProperty("过滤器集合")private List<IFilter> filters;public FilterChain(List<IFilter> filters) {this.filters = filters;}public List<Shape> doFilter(List<Shape> shapes) {if (CollectionUtils.isEmpty(filters) || CollectionUtils.isEmpty(shapes)) {return new ArrayList<>();}List<Shape> afterFilterShapes = new ArrayList<>(shapes);// 执行过滤for (IFilter filter : filters) {afterFilterShapes = filter.adaptFilter(afterFilterShapes);}return afterFilterShapes;}
}

3.4 测试主函数

package com.vinjcent.prototype.filter;import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;/*** @author vinjcent* 过滤模式*/
public class Main {public static void main(String[] args) {List<Shape> shapes = new ArrayList<>();shapes.add(new Shape("Circle", false, 0, "Curve"));shapes.add(new Shape("Triangle", true, 3, "Straight"));shapes.add(new Shape("Rectangle", true, 4, "Straight"));shapes.add(new Shape("Square", true, 4, "Straight"));shapes.add(new Shape("Oval", false, 0, "Curve"));shapes.add(new Shape("Sector", true, 2, "Curve and Straight"));CornerFilter cornerFilter = new CornerFilter();EdgeFilter edgeFilter = new EdgeFilter();CurveFilter curveFilter = new CurveFilter();// 具有角、边的形状FilterChain cornerAndEdgeFilterChain = new FilterChain(Arrays.asList(cornerFilter, edgeFilter));List<Shape> cornerAndEdgeShapes = cornerAndEdgeFilterChain.doFilter(shapes);System.out.println("具有角、边的形状:");printResult(cornerAndEdgeShapes);// 具有角、曲线的形状FilterChain cornerAndCurveFilterChain = new FilterChain(Arrays.asList(cornerFilter, curveFilter));List<Shape> cornerAndCurveShapes = cornerAndCurveFilterChain.doFilter(shapes);System.out.println("\n具有角、曲线的形状:");printResult(cornerAndCurveShapes);// 具有边、曲线的形状FilterChain edgeAndCurveFilterChain = new FilterChain(Arrays.asList(edgeFilter, curveFilter));List<Shape> edgeAndCurveShapes = edgeAndCurveFilterChain.doFilter(shapes);System.out.println("\n具有边、曲线的形状:");printResult(edgeAndCurveShapes);}public static void printResult(List<Shape> shapes) {for (Shape shape : shapes) {System.out.println("Shape{" +"name='" + shape.getName() + '\'' +", isCorner=" + shape.getIsCorner() +", edges=" + shape.getEdges() +", type='" + shape.getType() + '\'' +'}');}}}
  • 测试结果

在这里插入图片描述

4. 使用场景

  • 在某些场合,比如要对数据进行过滤,不仅仅局限于一个标准的情况下,进行分组,例如:数据查询、日志过滤、请求过滤

在这里插入图片描述

相关文章:

Java特性之设计模式【过滤器模式】

一、过滤器模式 概述 ​ 过滤器模式&#xff08;Filter Pattern&#xff09;或标准模式&#xff08;Criteria Pattern&#xff09;是一种设计模式&#xff0c;这种模式允许开发人员使用不同的标准来过滤一组对象&#xff0c;通过逻辑运算以解耦的方式把它们连接起来。这种类型的…...

Linux设备模型(十) - bus/device/device_driver/class

四&#xff0c;驱动的注册 1&#xff0c;struct device_driver结构体 /** * struct device_driver - The basic device driver structure * name: Name of the device driver. * bus: The bus which the device of this driver belongs to. * owner: The module own…...

性能问题分析排查思路之机器(3)

本文是性能问题分析排查思路的展开内容之一&#xff0c;第2篇&#xff0c;主要分为日志1期&#xff0c;机器4期、环境2期共7篇系列文章&#xff0c;本期是第三篇&#xff0c;讲机器&#xff08;硬件&#xff09;的网络方面的排查方法和最佳实践。 主要内容如图所示&#xff1a…...

PostgreSQL安装教程

系统环境 下载压缩包 下载压缩包 解压压缩包 查看解压文件 编译安装 编译 安装 用户权限和环境变量设置 创建用户 创建数据目录和日志目录 设置权限 设置环境变量 初始化数据库 数据库访问控制配置文件 postgresql.conf pg_hba.conf PostgreSQL启动与关闭 手…...

SLAM基础知识:前端和后端

在SLAM中前端和后端是被经常提到的一个概念。但是对于前端和后端的理解有着不同的看法&#xff0c;我的理解是&#xff1a; 前端&#xff1a;前端负责处理传感器数据&#xff0c;特征提取&#xff0c;进行状态估计和地图构建的初步步骤。 后端&#xff1a;后端接受不同时刻的里…...

一文彻底搞懂从输入URL到显示页面的全过程

简略版&#xff1a; 用户输入URL后&#xff0c;浏览器经过URL解析、DNS解析、建立TCP连接、发起HTTP请求、服务器处理请求、接收响应并渲染页面、关闭TCP连接等步骤&#xff0c;最终将页面显示给用户。 详细版&#xff1a; URL解析&#xff1a;浏览器根据用户输入的URL&#x…...

好书安利:《大模型应用开发极简入门:基于GPT-4和ChatGPT》这本书太好了!150页就能让你上手大模型应用开发

文章目录 前言一、ChatGPT 出现&#xff0c;一切都变得不一样了二、蛇尾书特色三、蛇尾书思维导图四、作译者简介五、业内专家书评总结 前言 ​如果问个问题&#xff1a;有哪些产品曾经创造了伟大的奇迹&#xff1f;ChatGPT 应该会当之无愧入选。仅仅发布 5 天&#xff0c;Chat…...

力扣题库第4题:移动零

题目内容&#xff1a; 给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 请注意 &#xff0c;必须在不复制数组的情况下原地对数组进行操作。 示例 : 输入: nums [0,1,0,3,12] 输出: [1,3,12,0,0] 答案&…...

Java解决IP地址无效化

Java解决IP地址无效化 01 题目 给你一个有效的 IPv4 地址 address&#xff0c;返回这个 IP 地址的无效化版本。 所谓无效化 IP 地址&#xff0c;其实就是用 "[.]" 代替了每个 "."。 示例 1&#xff1a; 输入&#xff1a;address "1.1.1.1" 输出…...

[数据结构初阶]队列

鼠鼠我呀&#xff0c;今天写一个基于C语言关于队列的博客&#xff0c;如果有兴趣的读者老爷可以抽空看看&#xff0c;很希望的到各位老爷观点和点评捏&#xff01; 在此今日&#xff0c;也祝各位小姐姐女生节快乐啊&#xff0c;愿笑容依旧灿烂如初阳&#xff0c;勇气与童真永不…...

MySQL学习Day27——MySQL事务日志

事务的隔离性由锁机制实现,而事务的原子性、一致性和持久性由事务的redo日志和undo日志来保证。其中REDO LOG称为重做日志,提供再写入操作,恢复提交事务修改的页操作,用来保证事务的持久性,redo log是存储引擎层生成的日志,记录的是物理级别上的页修改操作,主要为了保证…...

ETAS工具链ISOLAR-AB重要概念,RTE配置,ECU抽取

RTE配置界面&#xff0c;包含ECU抽取关联 首次配置RTE&#xff0c;出现需要勾选的抽取EXTRACT 创建System System制作SWC到ECU的Mapping System制作System Data 的Mapping...

蓝桥杯倒计时 43天 - 前缀和

思路&#xff1a;如果用n^2复杂度暴力会超时。nlogn 可以&#xff0c;利用前缀和化简&#xff0c;提前存储某个位置前的每个石头搬运到该位置和每个石头后搬运到该位置的前缀和On最后直接输出 On。排序花 nlogn #include<bits/stdc.h> using namespace std; typedef pai…...

【Web - 框架 - Vue】随笔 - Vue的简单使用(01) - 快速上手

【Web - 框架 - Vue】随笔 - Vue的简单使用(01) - 快速上手 Vue模板代码 代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>模板</title> </head> <body> <div></di…...

【简说八股】Redisson的守护线程是怎么实现的

Redisson Redisson 是一个 Java 语言实现的 Redis SDK 客户端&#xff0c;在使用分布式锁时&#xff0c;它就采用了「自动续期」的方案来避免锁过期&#xff0c;这个守护线程我们一般也把它叫做「看门狗」线程。 Redission是一个在Java环境中使用的开源的分布式缓存和分布式锁实…...

WPS/Office 好用的Word插件-查找替换

例如&#xff1a;一片文档&#xff1a;…………泰山…………泰&#xff08;少打了山字&#xff09;………… 要是把“泰”查找替换为“泰山”&#xff0c;就会把前面的“泰山”变成“泰山山”&#xff0c;这种问题除了再把“泰山山”查找替换为“泰山”&#xff0c;有没有更简单…...

Go 简单设计和实现可扩展、高性能的泛型本地缓存

相信大家对于缓存这个词都不陌生&#xff0c;但凡追求高性能的业务场景&#xff0c;一般都会使用缓存&#xff0c;它可以提高数据的检索速度&#xff0c;减少数据库的压力。缓存大体分为两类&#xff1a;本地缓存和分布式缓存&#xff08;如 Redis&#xff09;。本地缓存适用于…...

Vue.js 深度解析:模板编译原理与过程

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…...

Java多线程——如何保证原子性

目录 引出原子性保障原子性CAS 创建线程有几种方式&#xff1f;方式1&#xff1a;继承Thread创建线程方式2&#xff1a;通过Runnable方式3&#xff1a;通过Callable创建线程方式4&#xff1a;通过线程池概述ThreadPoolExecutor API代码实现源码分析工作原理&#xff1a;线程池的…...

stm32消息和邮箱使用

邮箱管里介绍 邮箱是C/OS-II中另一种通讯机制,它可以使一个任务或者中断服务子程序向另一个任务发送一个指针型的变量。该指针指向一个包含了特定“消息”的数据结构。为了在C/OS-II中使用邮箱,必须将OS_CFG.H中的OS_MBOX_EN常数置为1。使用邮箱之前,必须先建立该邮箱。该操…...

银行数字化转型导师坚鹏:银行数字化转型案例研究

银行数字化转型案例研究 课程背景&#xff1a; 数字化背景下&#xff0c;很多银行存在以下问题&#xff1a; 不清楚银行科技金融数智化案例&#xff1f; 不清楚银行供应链金融数智化案例&#xff1f; 不清楚银行普惠金融数智化案例&#xff1f; 不清楚银行跨境金融数智…...

142.乐理基础-音程的构唱练习

内容参考于&#xff1a;三分钟音乐社 上一个内容&#xff1a;141.乐理基础-男声女声音域、模唱、记谱与实际音高等若干问题说明-CSDN博客 本次内容最好去看视频&#xff1a; https://apphq3npvwg1926.h5.xiaoeknow.com/p/course/column/p_5fdc7b16e4b0231ba88d94f4?l_progra…...

【比较mybatis、lazy、sqltoy、mybatis-flex操作数据】操作批量新增、分页查询(二)

orm框架使用性能比较 环境&#xff1a; idea jdk17 spring boot 3.0.7 mysql 8.0比较mybatis、lazy、sqltoy、mybatis-flex操作数据 测试条件常规对象 orm 框架是否支持xml是否支持 Lambda对比版本mybatis☑️☑️3.5.4sqltoy☑️☑️5.2.98lazy✖️☑️1.2.4-JDK17-SNAPS…...

每日OJ题_链表②_力扣24. 两两交换链表中的节点

目录 力扣24. 两两交换链表中的节点 解析代码 力扣24. 两两交换链表中的节点 24. 两两交换链表中的节点 难度 中等 给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题&#xff08;即&…...

C语言数据类型详解及相关题——各种奇奇怪怪的偏难怪

文章目录 一、C语言基本数据类型溢出 二、存储原理符号位原码反码补码补码操作的例子 三、赋值中的类型转换常见返回类型——巨坑总结 一、C语言基本数据类型 溢出 因为数据范围&#xff08;即存储单元的位的数量&#xff09;的限制&#xff0c;可以表达的位数是有限的。 溢出…...

经典语义分割(二)医学图像分割模型UNet

经典语义分割(二)医学图像分割模型UNet 我们之前介绍了全卷积神经网络( FCN) &#xff0c;FCN是基于深度学习的语义分割算法的开山之作。 今天我们介绍另一个语义分割的经典模型—UNet&#xff0c;它兼具轻量化与高性能&#xff0c;通常作为语义分割任务的基线测试模型&#x…...

三天学会阿里分布式事务框架Seata-seata事务日志mysql持久化配置

锋哥原创的分布式事务框架Seata视频教程&#xff1a; 实战阿里分布式事务框架Seata视频教程&#xff08;无废话&#xff0c;通俗易懂版&#xff09;_哔哩哔哩_bilibili实战阿里分布式事务框架Seata视频教程&#xff08;无废话&#xff0c;通俗易懂版&#xff09;共计10条视频&…...

C语言-简单实现单片机中的malloc示例

概述 在实际项目中&#xff0c;有些单片机资源紧缺&#xff0c;需要mallloc内存&#xff0c;库又没有自带malloc函数时&#xff0c;此时&#xff0c;就需要手动编写&#xff0c;在此做个笔录。&#xff08;已在项目上使用&#xff09;&#xff0c;还可进入对齐管理机制。 直接…...

外包干了2年,技术退步明显

先说一下自己的情况&#xff0c;研究生&#xff0c;19年进入广州某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试&#xf…...

计算机网络面经-HTTPS加密过程

前言 在上篇文章HTTPS详解一中&#xff0c;我已经为大家介绍了 HTTPS 的详细原理和通信流程&#xff0c;但总感觉少了点什么&#xff0c;应该是少了对安全层的针对性介绍&#xff0c;那么这篇文章就算是对HTTPS 详解一的补充吧。还记得这张图吧。 HTTPS 和 HTTP的区别 显然&am…...