当前位置: 网站首页>小程序开发>400电话办理

林州网站建设【林州网络公司】林州做网站、林州微信公众号开发、林州网站设计、林州小程序制作

发表日期: 2021-05-06 14:17:32 浏览次数:128

林州网站建设【林州网络公司】林州做网站、林州微信公众号开发、林州网站设计、林州小程序制作


林州市,河南省直辖,由安阳市代管。位于河南省最北部的太行山东麓,地处豫、晋、冀三省交界处,是红旗渠的故乡,红旗渠精神发祥地。林州市总面积2046平方公里,辖4个街道、16个镇、1个国家级经济技术开发区。截止2017年,户籍人口116万人,人口密度每平方千米550.49人。 [1] 

汉高帝二年(公元前205年)置县,1994年撤县设市。林州市境内的林虑山是国家级重点风景名胜区,更有千古之谜猪叫石、三伏酷暑结冰的冰冰背、三九严寒桃花开的桃花谷、黄华流水颠倒颠的黄华山等自然奇观。红旗渠·太行大峡谷旅游区是国家5A级风景区 [2]  。

林州是最美中国人文(生态)旅游目的地城市、全国首批生态文明典范城市、中国低碳生态示范市、国际生态休闲示范城市 [3]  、国家全域旅游示范区 [4]  、国家园林城市、中国建筑之乡 [5]  、全国绿化模范市、全国卫生城市、全国文化模范市、全国科技工作先进市、国家知识产权试点市等,是全国最大的汽车配件生产基地、国家星火技术密集区、国家可持续发展实验区和河南省综合改革试点县(市)。

2018年,林州市生产总值590.9亿元,增长6. 3%。 [6] 


一、背景

以Java语言为例,说到可变的数据,就要提到函数式编程,函数式编程主要有以下概念: * 纯函数(Pure Function) * 头等函数和高阶函数(First-Class and High-Order functions) * 不可变性(Immutability) * 引用透明性(Referential Transparency)

Java作为编程语言的老大哥之一,是在JDK8的时候引入了函数式编程,java是一门面向对象的编程语言,在以前调用函数的时候总是需要依赖于一个对象,经常会写出匿名类这样的代码: Runnable runnable = new Runnable() { @Override public void run() { System.out.println("Hello World"); } }; JDK8中引入了函数式编程接口和Lambda来简化代码: Runnable runnable = () -> System.out.println("Hello World");

不可变性是函数式编程推崇的一个重要概念,保证数据的不可变性,从而可以让我们:开发更加简单、可回溯、测试友好,以及减少了任何可能的副作用,从而减少了Bug的出现。 但是JDK8对函数式编程的支持还不够完善,比如Collector的toXXX缺少生成不可变的集合,各种集合想要初始化一个不可变的对象也比较繁琐。当然这些问题在JDK11版本中得到了大幅度改进,不仅支持了类型推断,而且还支持了各种不可变对象的初始化,极大的简化了代码,比如: ``` // JDK7的常规初始化 ---------- 可变集合 List list = new ArrayList<>(); list.add("test01"); list.add("test02"); list.add("test03");

// JDK7的匿名内部类初始化 --- 可变集合 List list = new ArrayList<>() {{ add("test01"); add("test02"); add("test03"); }};

// JDK8的Stream初始化 ------ 可变集合 List list = Stream.of("test01", "test02", "test03").collect(Collectors.toList());

// JDK11的.of初始化 -------- 不可变集合 var list = List.of("test01", "test02", "test03");

// JDK11的stream初始化 ----- 不可变集合 var list = Stream.of("test01", "test02", "test03").collect(Colleactors.toUnmodifiableList());

// 借助工具类:Arrays ------- 不可变集合 List list = new ArrayList<>(Arrays.asList("test01", "test02", "test03"));

// 借助工具类:Collections List readList = Collections.unmodifiableList(list);

// 借助工具类:Guava ImmutableList list = ImmutableList.of("test01", "test02", "test03"); ``` 通过上面各种集合初始化的对比,相信你也能发现,JDK11对不可变性的支持也日益完善,函数式编程的很多优秀的特性在java语言得到了实现,所以还在用jdk8的小伙伴还是尽早升级,要不然jdk17都要出来了。

二、不可控的可变数据

在第一版java语言的《重构》书中,还没有发现可变数据的影子,也难怪,这本书是在2010年出版的,jdk8是在2012年第一次发布,但是随着函数式编程在这些高级语言中的应用,在2019年第二版js语言的《重构》书中,在代码的坏味道中会发现多了可变数据这一条。

下面介绍两种好用的重构手法,来避免不可控的可变数据为我们带来的麻烦。

1. 移除设置函数(Remove Setting Method)

和读数据相比,修改数据是一项危险的操作,这也就是为什么在并发编程中会有各种复杂的锁机制来保证数据的一致性。对于项目中的Model来说,setter方法就是其对外暴露不可控因素的源头,其实我们完全可以避免使用setter,通过不可变的方式来替代。详情可见3.1的代码样例部分。

2. 编写不可变类

Java中最典型的不可变类就是String类,里面的各种方法,只要涉及到字符串的变化,不会再原字符串上进行修改,而是生成一个新的字符串返回。 想要编写不可变类,也不难,只要做到以下三点: * 所有字段只在构造函数中初始化 * 若发生改变,就返回一个新对象 * 编程纯函数

三、代码案例,如何避免代码中的可变性

接下来的代码都以jdk11版本的语法为例,部分代码为伪代码只为说明逻辑:

1. 基本数据类型、包装类和String

基本数据类型 :int、long、float、double、byte、short、boolean、char 包装类 :Integer、Long、Float、Double、Byte、Short、Boolean、Character String 本身是不可变类

// 在使用以上数据类型申请变量时, 应该尽量避免对同一个变量反复赋值 int i = toResult(); .... i = toAnotherResult(); // toAnotherResult()应该重新申请一个变量,不应该对以前的变量进行覆盖,并且不必要的变量应该进行Inline操作 还有一种情况在开发的时候会经常遇到: ``` // 第一种情况,if中只有一行赋值代码 String s1; if(isRight(xxx)) { s1 = "test_01"; } else { s1 = "test_02"; } use String s1 do something ...

// 第二种情况, if中内嵌了多行代码 String s2; if(isRight(xxx)) { do something ... s1 = "test_01"; } else { do something ... s1 = "test_02"; } use String s2 do something ... 上面这种情况应该在初始化的时候就给变量赋值。 // 第一种情况可以使用三目运算符来解决: String s1 = isRight(xxx) ? "test_01" : "test_02";

// 第二种情况可以使用Extract Method(提炼函数)来解决: String s2 = toStr(xxx);

private String toStr(xxx) { //使用卫语句简化if-else结构 if(isRight(xxx)) { do something ... return "test_01"; } do something ... return "test_02"; }

```

2. 构建不可变的集合

集合类型 :List、Map、Set, 下面List为例来说明

下列情况应当避免: ``` // 避免: 初始化可变列表 List list = new ArrayList<>() {{ add("test01"); add("test02"); add("test03"); }};

// 避免: 在一个方法中改变参数列表的长度 public void change(List list) { list.add("test04"); }

// 避免: 在一个方法中改变参数列表的内部值 public void fill(List models) { models.foreach(model -> model.setType("new_model")); } 构建不可变的列表: // 初始化 var list_01 = List.of("test01", "test02", "test03", ""); var list_02 = List.of("test04", "test05", "test06", "");

// 通过stream来实现列表的合并和过滤,创建一个新的不可变集合 // 两个集合合并 var list_03 = Stream.concat(list_01.stream(), list_02.stream()).collect(Collectors.toUnmodifiableList()); // 多个集合合并 var list_04 = Stream.of(list1.stream(), list2.stream(), list3.stream()).flatMap(Function.identity()).collect(Collectors.toUnmodifiableList()); // 集合过滤 var list_05 = list_04.stream().filter(StringUtils::isNotEmpty).collect(Collectors.toUnmodifiableList());

// 集合改变内部的值生成一个新的集合,这里的model代表一个虚拟的对象 var models = List.of(model1, model2, model3); var newModels = models.stream().map(model -> model.withType("new_model")).collect(Collectors.toUnmodifiableList()); ``` 总之: 集合搭配Stream可以进行任何变化生成新的不可变集合,没有副作用,非常的nice。

3. 构建不可变的model

@Setter是导致model可变的罪魁祸首,其实我们完全可以不使用setter来构建我们的model,可以在lombok中把setter相关的禁用掉。 lombok.setter.flagUsage = error lombok.data.flagUsage = error 我们可以用以下注释来构建不可见的model,并且通过staticName = "of"让model的构建更加函数式化。 ``` // 声明 @With @Getter @Builder(toBuilder = true) @AllArgsConstructor(staticName = "of") @NoArgsConstructor(staticName = "of") public class Model() { private String id; private String name; private String type; }

// 构建Model var model_01 = Model.of("101", "model_01", "model");

// 构建空Model var model_02 = Model.of();

// 构建指定参数的Model var model_03 = Moder.toBuilder().id("301").name("model_03").build();

// 修改Model的一个值,通过@With来生成一个全新的model var model_04 = model_01.withName("model_04");

// 修改多个值,通过@Builder来生成一个全新的model var model_05 = model_01.toBuilder.name("model_05").type("new_model").build(); ```

四、总结

编写代码时,时刻提醒自己:控制数据的可变性 😂😂😂😂😂😂😂😂😂😂😂😂😂😂


微信图片_20210425092605.jpg


林州网站建设林州网络公司林州做网站、林州微信公众号开发、林州网站设计、林州小程序制作

400-111-6878
服务热线
顶部

备案号: 苏ICP备11067224号

CopyRight © 2011 书生商友信息科技 All Right Reserved

24小时服务热线:400-111-6878   E-MAIL:1120768800@qq.com   QQ:1120768800

  网址: https://www.768800.com  网站建设上往建站

关键词: 网站建设| 域名邮箱| 服务器空间| 网站推广| 上往建站| 网站制作| 网站设计| 域名注册| 网络营销| 网站维护|

企业邮箱| 虚拟主机| 网络建站| 网站服务| 网页设计| 网店美工设计| 网站定制| 企业建站| 网站设计制作| 网页制作公司|

400电话办理| 书生商友软件| 葬花网| 调温纤维| 海洋馆运营维护| 北京保安公司| 殡仪馆服务| 殡葬服务| 昌平殡葬| 朝阳殡葬|

预约专家

欢迎您免费咨询,请填写以下信息,我们收到后会尽快与您联系

  

服务热线:400-111-6878