蒲丰投针实验原理_布丰投针实验 MATLAB仿真 以及报告
布丰投针实验原理、仿真过程以及 MATLAB仿真代码、完整的布丰投针实验报告。
以下内容无关:
-------------------------------------------分割线---------------------------------------------
本文的焦点将集中在上文留下的4个类型转换器上。
StreamConverter:将Stream流与集合/数组之间的转换,必要时转换元素类型
这三个比较特殊,属于“最后的”“兜底类”类型转换器:
ObjectToObjectConverter:通用的将原对象转换为目标对象(通过工厂方法or构造器)
IdToEntityConverter:本文重点。给个ID自动帮你兑换成一个Entity对象
FallbackObjectToStringConverter:将任何对象调用toString()转化为String类型。当匹配不到任何转换器时,它用于兜底
默认转换器注册情况
Spring新一代类型转换内建了非常多的实现,这些在初始化阶段大都被默认注册进去。注册点在DefaultConversionService提供的一个static静态工具方法里:
static静态方法具有与实例无关性,我个人觉得把该static方法放在一个xxxUtils里统一管理会更好,放在具体某个组件类里反倒容易产生语义上的误导性
public static void addDefaultConverters(ConverterRegistry converterRegistry) {
// 1、添加标量转换器(和数字相关)
addScalarConverters(converterRegistry);
// 2、添加处理集合的转换器
addCollectionConverters(converterRegistry);
// 3、添加对JSR310时间类型支持的转换器
converterRegistry.addConverter(new ByteBufferConverter((ConversionService) converterRegistry));
converterRegistry.addConverter(new StringToTimeZoneConverter());
converterRegistry.addConverter(new ZoneIdToTimeZoneConverter());
converterRegistry.addConverter(new ZonedDateTimeToCalendarConverter());
// 4、添加兜底转换器(上面处理不了的全交给这几个哥们处理)
converterRegistry.addConverter(new ObjectToObjectConverter());
converterRegistry.addConverter(new IdToEntityConverter((ConversionService) converterRegistry));
converterRegistry.addConverter(new FallbackObjectToStringConverter());
converterRegistry.addConverter(new ObjectToOptionalConverter((ConversionService) converterRegistry));
}
}
该静态方法用于注册全局的、默认的转换器们,从而让Spring有了基础的转换能力,进而完成绝大部分转换工作。为了方便记忆这个注册流程,我把它绘制成图供以你保存:
特别强调:转换器的注册顺序非常重要,这决定了通用转换器的匹配结果(谁在前,优先匹配谁)。
针对这幅图,你可能还会有疑问:
JSR310转换器只看到TimeZone、ZoneId等转换,怎么没看见更为常用的LocalDate、LocalDateTime等这些类型转换呢?难道Spring默认是不支持的?
答:当然不是。 这么常见的场景Spring怎能会不支持呢?不过与其说这是类型转换,倒不如说是格式化更合适。所以会在后3篇文章格式化章节在作为重中之重讲述
一般的Converter都见名之意,但StreamConverter有何作用呢?什么场景下会生效
答:本文讲述
对于兜底的转换器,有何含义?这种极具通用性的转换器作用为何
答:本文讲述
StreamConverter
用于实现集合/数组类型到Stream类型的互转,这从它支持的Set 集合也能看出来:
@Override
public Set getConvertibleTypes() {
Set convertiblePairs = new HashSet();
convertiblePairs.add(new ConvertiblePair(Stream.class, Collection.class));
convertiblePairs.add(new ConvertiblePair(Stream.class, Object[].class));
convertiblePairs.add(new ConvertiblePair(Collection.class, Stream.class));
convertiblePairs.add(new ConvertiblePair(Object[].class, Stream.class));
return convertiblePairs;
}
它支持的是双向的匹配规则:
代码示例{@link StreamConverter}
*/
@Test
public void test2() {
System.out.println("----------------StreamConverter---------------");
ConditionalGenericConverter converter = new StreamConverter(new DefaultConversionService());
TypeDescriptor sourceTypeDesp = TypeDescriptor.valueOf(Set.class);
TypeDescriptor targetTypeDesp = TypeDescriptor.valueOf(Stream.class);
boolean matches = converter.matches(sourceTypeDesp, targetTypeDesp);
System.out.println(“是否能够转换:” + matches);
// 执行转换
Object convert = converter.convert(Collections.singleton(1), sourceTypeDesp, targetTypeDesp);
System.out.println(convert);
System.out.println(Stream.class.isAssignableFrom(convert.getClass()));
}
运行程序,输出:
1
2
3
4
----------------StreamConverter---------------
是否能够转换:true
java.util.stream.ReferencePipeline$Head@5a01ccaa
true
关注点:底层依旧依赖DefaultConversionService完成元素与元素之间的转换。譬如本例Set -> Stream的实际步骤为:
也就是说任何集合/数组类型是先转换为中间状态的List,最终调用list.stream()转换为Stream流的;若是逆向转换先调用source.collect(Collectors.toList())把Stream转为List后,再转为具体的集合or数组类型。
说明:若source是数组类型,那底层实际使用的就是ArrayToCollectionConverter,注意举一反三
使用场景
StreamConverter它的访问权限是default,我们并不能直接使用到它。通过上面介绍可知Spring默认把它注册进了注册中心里,因此面向使用者我们直接使用转换服务接口ConversionService便可。
1
2
3
4
5
6
7
8
9
10
@Test
public void test3() {
System.out.println("----------------StreamConverter使用场景---------------");
ConversionService conversionService = new DefaultConversionService();
Stream result = conversionService.convert(Collections.singleton(1), Stream.class);
// 消费
result.forEach(System.out::println);
// result.forEach(System.out::println); //stream has already been operated upon or closed
}
运行程序,输出:
1
2
----------------StreamConverter使用场景---------------
1
再次特别强调:流只能被读(消费)一次。
因为有了ConversionService提供的强大能力,我们就可以在基于Spring/Spring Boot做二次开发时使用它,提高系统的通用性和容错性。如:当方法入参是Stream类型时,你既可以传入Stream类型,也可以是Collection类型、数组类型,是不是瞬间逼格高了起来。
兜底转换器
按照添加转换器的顺序,Spring在最后添加了4个通用的转换器用于兜底,你可能平时并不关注它,但它实时就在发挥着它的作用。
ObjectToObjectConverter
将源对象转换为目标类型,非常的通用:Object -> Object:
1
2
3
4
@Override
public Set getConvertibleTypes() {
return Collections.singleton(new ConvertiblePair(Object.class, Object.class));
}
虽然它支持的是Object -> Object,看似没有限制但其实是有约定条件的:
1
2
3
4
5
@Override
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
return (sourceType.getType() != targetType.getType() &&
hasConversionMethodOrConstructor(targetType.getType(), sourceType.getType()));
}
是否能够处理的判断逻辑在于hasConversionMethodOrConstructor方法,直译为:是否有转换方法或者构造器。代码详细处理逻辑如下截图:
此部分逻辑可分为两个part来看:
part1:从缓存中拿到Member,直接判断Member的可用性,可用的话迅速返回
part2:若part1没有返回,就执行三部曲,尝试找到一个合适的Member,然后放进缓存内(若没有就返回null)
part1:快速返回流程
当不是首次进入处理时,会走快速返回流程。也就是第0步isApplicable判断逻辑,有这几个关注点:
Member包括Method或者Constructor
Method:若是static静态方法,要求方法的第1个入参类型必须是源类型sourceType;若不是static方法,则要求源类型sourceType必须是method.getDeclaringClass()的子类型/相同类型
Constructor:要求构造器的第1个入参类型必须是源类型sourceType
创建目标对象的实例,此转换器支持两种方式:
通过工厂方法/实例方法创建实例(method.invoke(source))
通过构造器创建实例(ctor.newInstance(source))
以上case,在下面均会给出代码示例。
part2:三部曲流程
对于首次处理的转换,就会进入到详细的三部曲逻辑:通过反射尝试找到合适的Member用于创建目标实例,也就是上图的1、2、3步。
step1:determineToMethod,从sourceClass里找实例方法,对方法有如下要求:
方法名必须叫"to" + targetClass.getSimpleName(),如toPerson()
方法的访问权限必须是public
该方法的返回值必须是目标类型或其子类型
step2:determineFactoryMethod,找静态工厂方法,对方法有如下要求:
方法名必须为valueOf(sourceClass) 或者 of(sourceClass) 或者from(sourceClass)
方法的访问权限必须是public
step3:determineFactoryConstructor,找构造器,对构造器有如下要求:
存在一个参数,且参数类型是sourceClass类型的构造器
构造器的访问权限必须是public
特别值得注意的是:此转换器不支持Object.toString()方法将sourceType转换为java.lang.String。对于toString()支持,请使用下面介绍的更为兜底的FallbackObjectToStringConverter。
蒲丰投针实验原理_布丰投针实验 MATLAB仿真 以及报告相关推荐
- 万丰科技机器人排名_万丰科技拟“借壳”长春经开
继ST亚星重组济南"老字号"宏济堂拿下2020年借壳第一单之后,2020年借壳第二单有望花落长春经开. 长春经开1月15日晚间披露重大资产重组预案,拟以发行股份及支付现金的方式,向 ...
- 苹果手机投屏软件_苹果手机怎样投屏到电脑上操作,用什么软件?
金舟苹果手机投屏软件是一款专业的苹果手机投屏软件,支持苹果手机投屏至Windows系统,支持投屏录制.全屏投屏.截屏.白板等功能,全方位解决您的问题! 功能介绍 1.旋转 无需手机操作,软件界面也是可 ...
- 顺丰java面试题_顺丰java开发面试分享,顺丰java面试经面试题
今天要给大家分享的是一个小伙伴的顺丰java开发面试过程,其中包括了面试流程,面试题目,和回答,感兴趣的朋友可以来了解一下哈. 一.面试流程 是中午进行的面试,首先是做自我介绍,之后就是讲一下项目,然 ...
- 苹果手机投屏软件_苹果手机怎么投屏到电脑上?支你一招
苹果手机一次次升级都会给我们带来不一样的体验感,airplay投屏便是苹果手机系统中很好的一大特色,有了它你就可以轻松把手机文档投电脑,电脑投屏电视,手机视频.手机音乐投屏到电脑等等. 比如说工作中我 ...
- 安卓手机投屏软件_手机车载投屏的方法安卓、苹果都支持
昨天有用户咨询说他想手机投屏到他的车载显示屏上,经过一番探讨,最后咨询那哥们终于用MHL线进行手机屏幕和车载屏幕连接成功了.事后小编采集了一些手机投屏到车载显示屏上的方法,希望对大家有用. 解决方案一 ...
- 安卓手机投屏软件_安卓手机投屏竟然这么简单,每个安卓手机都可以!
很多人问到安卓系统的手机怎么投屏的问题,因为除了一些新款手机.以前的老版安卓手机很多是不自带投屏功能的,那么对于以前的老版安卓手机而言,怎么做到投屏呢?其实这个问题非常容易解决,不多说,我们来看下解决 ...
- 蒸发器分段设计matlab程序_制冷系统蒸发器过热度控制回路的MATLAB仿真_何煜
. 王志刚 710049 陕西西安市西安交通大学能源与动力学院 制冷系统蒸发器过热度控制回路的 M A T LAB 仿真 上海交通大学 何 煜 仲 华 唐双波 陈芝久 摘 要 根据 实际制冷 系统的电 ...
- saber仿真软件_电力电子应用技术的MATLAB仿真
欢迎加入技术交流QQ群(2000人):电力电子技术与新能源 905723370 高可靠新能源行业顶尖自媒体 在这里有电力电子.新能源干货.行业发展趋势分析.最新产品介绍.众多技术达人与您分享经验,欢迎 ...
- R语言对布丰投针(蒲丰投针)实验进行模拟和动态可视化生成GIF动画
最近我们被客户要求撰写关于动态可视化的研究报告,包括一些图形和统计输出. 介绍 布丰投针是几何概率领域中最古老的问题之一.它最早是在1777年提出的.它将针头掷到有平行线的纸上,并确定针和其中一条平行 ...
最新文章
- 松江库卡机器人_上海高质量发展调研行|库卡机器人:为全球提供“松江创造”的产品...
- Java线程池详解学习:ThreadPoolExecutor
- java绘制地球绕太阳转_Unity3D 公转小案例:地球围绕太阳转
- CentOS6.7安装jdk1.8
- MaxCompute 实现增量数据推送(全量比对增量逻辑)
- 8.String、StringBuffer、enum枚举
- 问题2----网速问题?造成的ORA-01034和ORA-27101
- (转)拿到软银44亿美金巨资后,WeWork要这样布局中国市场
- 禁止百度云盘p2p后台上传
- eclipse导入html页面乱码,Eclipse导入项目乱码问题(中文乱码)
- Android Wi-Fi源码分析之wpa_supplicant初始化(三):wpa_supplicant_add_iface函数分析
- 数据分析师笔试题(一)
- c语言中偶数的平方while,在C语言中可以用以下语句来实现循环:1. 用while语句;2. ...新版1127.ppt...
- 魅族flashfire_魅族Pro6s更新安卓7.1后完美root及xp框架
- 概率论基础 - 7 - 特征函数
- camera模组 ------- super Good
- 车载摄像头在ADAS中的应用
- ffmpeg命令分析-t
- 五年级计算机教案上册,五年级上册信息技术教案【三篇】
- 学习C#必备的编程软件——pow_na的博客
热门文章
- 私有云、公有云还是混合云?
- 2021年07月虹科Pico汽车示波器简报
- visual studio性能探查器
- 传说中Google AdWords黄金账户的标准
- python:pyecharts地图功能,并解决显示不全或只显示南海诸岛问题解决,其实很简单
- ftrace--------------trace points
- 渗透测试工具—xray
- 航空公司客户价值分析(附完整代码)
- 2023年新课标I卷作文,5位人工智能考生(ChatGPT,文心一言,GPT4, ChatGLM-6b, ChatT5)来写作,看谁写得最好
- 安科瑞交直流充电桩用电计量方案-Susie 周