Vavr core是一个Java函数库。它有助于减少代码量并提高健壮性。函数式编程的第一步是开始思考不可变的值。Vavr 提供不可变的集合以及必要的函数和控制结构来操作这些值。
Java缺少元组的一般概念。元组将固定数量的元素组合在一起,以便它们可以作为一个整体传递。与数组或列表不同,元组可以保存不同类型的对象,但它们也是不可变的。 元组的类型为 Tuple1、Tuple2、Tuple3 等。目前有 8 个元素的上限。要访问元组的元素,可以使用方法访问第一个元素,访问第二个元素,依此类推。tt._1t._2
通过Tuple.of()静态工厂方法创建元组,元组的类型为Tuple2,元组的元素类型为Integer和String,元组的元素个数为2,元组的元素下标从1开始。
通过map()方法逐个映射元组组件,map()方法的参数为一个函数,函数的参数为元组的元素,函数的返回值为一个新的元组。
通过map()方法使用一个映射函数映射元组组件,map()方法的参数为一个函数,函数的参数为元组的元素,函数的返回值为一个新的元组。
通过apply()方法变换元组,apply()方法的参数为一个函数,函数的参数为元组的元素,函数的返回值为一个新的元组。
函数式编程是关于使用函数进行值和值转换的。Java 8 只提供了一个接受一个参数和一个接受两个参数的参数。Vavr 提供的功能最多为 8 个参数。功能接口被调用等。
通过匿名类创建函数,匿名类的参数为函数的参数,匿名类的返回值为函数的返回值。
通过andThen()方法组合函数,andThen()方法的参数为一个函数,函数的参数为当前函数的返回值,函数的返回值为一个新的函数。
通过compose()方法组合函数,compose()方法的参数为一个函数,函数的参数为当前函数的参数,函数的返回值为一个新的函数。
andThen()和compose()的区别在于参数的顺序不同,andThen()方法的参数为一个函数,函数的参数为当前函数的返回值,compose()方法的参数为一个函数,函数的参数为当前函数的参数。 上边说的解释可能太官方了,大概理解为andThen()方法是先执行当前函数,再执行参数函数,compose()方法是先执行参数函数,再执行当前函数。
您可以将部分函数提升为返回结果的总函数。术语偏函数来自数学。从 X 到 Y 的部分函数是函数 f:X′ → Y,对于 X 的某个子集 X′。它推广了函数 f:X → Y 的概念,不强制 f 将 X 的每个元素映射到 Y 的元素。这意味着部分函数仅对某些输入值正常工作。如果使用不允许的输入值调用函数,它通常会引发异常。
通过lift()方法提升函数,lift()方法的参数为一个函数,函数的参数为当前函数的参数,函数的返回值为一个新的函数,新的函数的返回值为一个Option。
部分应用程序允许您通过修复某些值从现有函数派生新函数。您可以修复一个或多个参数,固定参数的数量定义了新函数的 arity,例如 .参数从左到右绑定
通过apply()方法部分应用函数,可以先传一个参数再传一个在传一个从左到右一次绑定
区别
记忆是缓存的一种形式。记忆函数仅执行一次,然后从缓存返回结果。 下面的示例在第一次调用时计算一个随机数,并在第二次调用时返回缓存的数字。
肯定大多数人不太理解这个memoized和普通变量声明有什么区别,其实这个memoized是一个函数,这个函数的返回值是一个随机数,但是这个函数只会执行一次,第二次调用的时候会直接返回第一次调用的结果,这就是memoized的作用。 普通变量声明
配置设置: 当你有一个固定的值(如配置信息)需要在整个应用程序中使用时。
配置设置: 当你有一个固定的值(如配置信息)需要在整个应用程序中使用时。
单次计算: 当你只需要进行一次计算并存储结果时。
状态存储: 当你需要在应用程序的生命周期内维护某种状态时。
临时变量: 在循环或条件语句中作为临时存储。
.memoized()
缓存计算密集型操作: 如果你有一个计算密集型的操作,多次调用它是不高效的,你可以使用 .memoized()
来缓存结果。
懒加载: 如果你有一个操作可能不会被立即需要,或者可能根本就不需要,使用 Function0 会更高效。
函数组合: 当你需要将多个函数组合在一起进行复杂的操作时,使用 Function0 可以更容易地实现函数组合。
高阶函数: 当你需要将函数作为参数传递或从另一个函数返回函数时。
测试与模拟: 使用 Function0 可以更容易地在单元测试中模拟依赖。
用法可以参考Stream-Query的Opp
用法可以参考Stream-Query的Opp中的ofTry
惰性是表示惰性求值的 monadic 容器类型。与Supplier相比,Lazy 是记忆的,即它只评估一次,因此在引用上是透明的。
通过Lazy.of()方法创建Lazy,Lazy.of()方法的参数为一个函数,函数的返回值为Lazy的值,Lazy的值只会计算一次,之后再调用get()方法都会返回第一次计算的值。
Either 表示一个值是左值还是右值。通常,左值用于错误,右值用于成功。默认情况下,Either 是一个不可变的类型,但是您可以使用 Either.left() 和 Either.right() 创建可变的 Either。
这个方法还是挺有意思的,大多数情况下成功设定为返回右边的值,失败返回左边的值,这样就可以通过isRight()方法判断是否成功,通过get()方法获取值,通过getLeft()方法获取错误信息。 还可以对返回成功的值进行一些列的操作也可以使用toEither()自定义失败的返回值
验证控件是一个应用函子,有助于累积错误。当尝试组合Monads时,组合过程将在第一次遇到错误时短路。但是“验证”将继续处理组合函数,累积所有错误。这在验证多个字段(例如 Web 表单)时特别有用,并且您希望知道遇到的所有错误,而不是一次一个错误。
为了设计一个全新的Java集合库,它满足了函数式编程的要求,即不变性,已经投入了很多精力。
Java的Stream将计算提升到不同的层,并在另一个显式步骤中链接到特定的集合。有了Vavr,我们不需要所有这些额外的样板。
Vavr 是一个不可变的链表。突变会创建新的实例。大多数操作都是线性时间执行的。后续操作将逐个执行。
因为Vavr引入了元组的说明那么与JDK8的Stream相比,Vavr新增了好多便捷的方法以及新特性这里举一个例子
将一个list转换为Map
这个特性需要引入
通过Arbitrary.integer()方法创建一个随机数,然后通过Property.def()方法创建一个属性,然后通过forAll()方法传入随机数,然后通过suchThat()方法传入一个函数,函数的返回值为boolean,最后通过check()方法检查属性是否满足,最后通过assertIsSatisfied()方法断言属性是否满足。
模式匹配是一种功能,它允许您根据值的类型和结构执行不同的操作。模式匹配是函数式编程的一个重要特性,因为它允许您编写更简洁,更可读的代码。
单值匹配,通过Match(),如果值为null可以通过()匹配,如果值不为null可以通过(value)匹配
断言也就是使用lambda表达式Predicate进行匹配
Vavr内部还提供了一些常用的断言,比如is(),isIn(),isNotNull(),isNull(),isOneOf(),isZero()等等 比如