1. Overview
1.概述
Vavr is an open source object-functional language extension library for Java 8+. It helps to reduce the amount of code and to increase the robustness.
Vavr是一个用于Java 8+的开源对象功能语言扩展库。它有助于减少代码量并提高健壮性。
In this article, we’ll learn about Vavr‘s tool called Either. If you want to learn more about the Vavr library, check this article.
在这篇文章中,我们将了解Vavr的工具,称为Either。如果你想了解更多关于Vavr库的信息,查看这篇文章。
2. What Is Either?
2.什么是Either?
In a functional programming world, functional values or objects can’t be modified (i.e. in normal form); in Java terminology, it’s known as immutable variables.
在函数式编程的世界里,函数式值或对象不能被修改(即以正常形式);在Java术语中,它被称为不可变的变量。
Either represents a value of two possible data types. An Either is either a Left or a Right. By convention, the Left signifies a failure case result and the Right signifies a success.
Either代表两种可能的数据类型的值。Either是Left或Right。根据惯例,Left表示一个失败的案例结果,Right表示一个成功的案例。
3. Maven Dependencies
3.Maven的依赖性
We need to add the following dependency in the pom.xml:
我们需要在pom.xml中添加以下依赖关系。
<dependency>
<groupId>io.vavr</groupId>
<artifactId>vavr</artifactId>
<version>0.9.0</version>
</dependency>
The latest version of Vavr is available in the Central Maven Repository.
Vavr的最新版本可在Central Maven Repository中找到。
4. Use Cases
4.使用案例
Let’s consider a use case where we need to create a method which takes an input and, based on the input, we’ll return either a String or an Integer.
让我们考虑一个用例,我们需要创建一个接受输入的方法,根据输入,我们将返回一个String或一个Integer。
4.1. Plain Java
4.1.纯粹的Java
We can implement this in two ways. Either our method can return a map with the key representing success/failure result, or it could return a fixed size List/Array where position denotes a result type.
我们可以通过两种方式实现这一点。要么我们的方法可以返回一个键代表成功/失败结果的地图,要么它可以返回一个固定大小的List/Array,其中位置表示一个结果类型。
This is how this could look like:
这可以是这样的。
public static Map<String, Object> computeWithoutEitherUsingMap(int marks) {
Map<String, Object> results = new HashMap<>();
if (marks < 85) {
results.put("FAILURE", "Marks not acceptable");
} else {
results.put("SUCCESS", marks);
}
return results;
}
public static void main(String[] args) {
Map<String, Object> results = computeWithoutEitherUsingMap(8);
String error = (String) results.get("FAILURE");
int marks = (int) results.get("SUCCESS");
}
For the second approach, we could use the following code:
对于第二种方法,我们可以使用以下代码。
public static Object[] computeWithoutEitherUsingArray(int marks) {
Object[] results = new Object[2];
if (marks < 85) {
results[0] = "Marks not acceptable";
} else {
results[1] = marks;
}
return results;
}
As we can see, both ways require quite a lot of work, and the final result is not very aesthetically appealing nor safe to use.
正如我们所看到的,这两种方式都需要相当多的工作,而且最终的结果不是很美观,也不能安全地使用。
4.2. With Either
4.2.与Either一起
Now let’s see how we can utilize Vavr‘s Either utility to achieve the same result:
现在让我们看看如何利用Vavr的Either工具来实现同样的结果。
private static Either<String, Integer> computeWithEither(int marks) {
if (marks < 85) {
return Either.left("Marks not acceptable");
} else {
return Either.right(marks);
}
}
No, explicit type-casting, null checking, or unused object creation is required.
没有,需要显式的类型转换、空值检查或未使用的对象创建。
Moreover, Either provides a very handy monadic-like API for dealing with both cases:
此外,Either提供了一个非常方便的类似单数的API来处理这两种情况。
computeWithEither(80)
.right()
.filter(...)
.map(...)
// ...
By convention, Either’s Left attribute represents a failure case and the Right one represents a success. However, based on our needs we can change this using projections – Either in Vavr is not biased towards Left or Right.
按照惯例,Either的Left属性代表失败的情况,而Right则代表成功。然而,根据我们的需要,我们可以使用投影来改变这一点–Vavr中的Either不偏向于Left或Right。
If we project to Right, operations like filter(), map() will have no effect if Either was Left.
如果我们投射到右边,像filter()、map()这样的操作将没有效果,如果Either是左边。
For example, let’s create the Right projection and define some operations on it:
例如,让我们创建Right投影并对其定义一些操作。
computeWithEither(90).right()
.filter(...)
.map(...)
.getOrElse(Collections::emptyList);
If it turns out that we projected Left to the Right, we will get an empty list immediately.
如果结果是我们把左边投射到右边,我们将立即得到一个空列表。
We can interact with the Left projection in a similar way:
我们可以用类似的方式与Left投影互动。
computeWithEither(9).left()
.map(FetchError::getMsg)
.forEach(System.out::println);
4.3. Additional Features
4.3.附加功能
There are plenty of Either utilities available; let’s have a look at some of them.
有很多Either工具可用,让我们看看其中的一些。
We can check if an Either contain only Left or Right using isLeft and isRight methods:
我们可以使用isLeft和isRight方法检查一个Either是否只包含Left或Right。
result.isLeft();
result.isRight();
We can check if Either contains a given Right value:
我们可以检查Either是否包含一个给定的Right值。
result.contains(100)
We can fold Left and Right to one common type:
我们可以折叠左和右为一个共同类型。
Either<String, Integer> either = Either.right(42);
String result = either.fold(i -> i, Object::toString);
or… even swap sides:
或者……甚至交换立场。
Either<String, Integer> either = Either.right(42);
Either<Integer, String> swap = either.swap();
5. Conclusion
5.结论
In this quick tutorial, we’ve learned about using the Either utility of Vavr‘s framework. More details on Either can be found here.
在这个快速教程中,我们已经了解了使用Vavr框架的Either工具。关于Either的更多细节可以在这里找到。
As always, the full source code is available over on GitHub.
一如既往,完整的源代码可在GitHub上获得,。