曹耘豪的博客

使用vavr

  1. 模式匹配
    1. 常用import
    2. 简单匹配
    3. 匹配Tuple
    4. 匹配Try
    5. 对自定义类型进行匹配
    6. 一点优化
  2. Either

模式匹配

常用import

1
2
3
4
import static io.vavr.API.$;
import static io.vavr.API.Case;
import static io.vavr.API.Match;
import static io.vavr.Patterns.$Tuple2;

简单匹配

1
2
3
4
5
6
7
8
var name = 1;

String greetMsg = Match(name).of(
Case($(1), "yes"),
Case($(), "no")
);

assertEquals("yes", greetMsg);

匹配Tuple

1
2
3
4
5
6
7
8
9
var t = Tuple.of(1, "joy");

String greetMsg = Match(t).of(
Case($Tuple2($(1), $()), (a, b) -> "hello " + b),
Case($(e -> e._1 == 1), "123"),
Case($(), "unknown")
);

assertEquals("hello joy", greetMsg);

匹配Try

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import static io.vavr.API.Try;
import static io.vavr.Patterns.$Failure;
import static io.vavr.Patterns.$Success;

var s = Try(() -> 1);

String r = Match(s).of(
Case($Success($()), "success"),
Case($Failure($()), "failure"),
Case($(), "failure")
);

assertEquals("success", r);

var f = Try(() -> 1 / 0);

String r2 = Match(f).of(
Case($Success($()), "success"),
Case($Failure($(e -> RuntimeException.class.isAssignableFrom(e.getClass()))), "runtime exception"),
Case($Failure($()), "failure"),
Case($(), "unknown")
);

assertEquals("runtime exception", r2);

对自定义类型进行匹配

1
2
3
4
5
6
7
8
var p = new Person(1, "joy");

String greetMsg = Match(p).of(
Case(Person.$id(1), (id, name) -> "hello " + name),
Case($(), () -> "unknown")
);

assertEquals("hello joy", greetMsg);

其中Person如下

1
2
3
4
5
6
7
8
9
@AllArgsConstructor
public static class Person {
Integer id;
String name;

public static Match.Pattern2<Person, Integer, String> $id(Integer id) {
return Match.Pattern2.of(Person.class, $(id), $(), _p -> Tuple.of(_p.id, _p.name));
}
}

一点优化

match的of参数每次需创建n个Case,可使用Supplier优化效率,如下代码

1
2
3
4
5
6
7
8
9
10
11
12
@SafeVarargs
public static <T, R> R match(T value, Supplier<Match.Case<? extends T, ? extends R>> ...cases) {
Objects.requireNonNull(cases, "cases is null");
for (var _case : cases) {
@SuppressWarnings("unchecked")
var __case = (Match.Case<T, R>) _case.get();
if (__case.isDefinedAt(value)) {
return __case.apply(value);
}
}
throw new IllegalStateException();
}

使用方式,增加() ->即可,一个小优化

1
2
3
4
5
6
7
8
var p = new Person(1, "joy");

String greetMsg = match(p,
() -> Case(Person.$id(1), (id, name) -> "hello " + name),
() -> Case($(), "unknown")
);

assertEquals("hello joy", greetMsg);

Either

left代表失败,right代表成功

1
2
3
4
5
6
7
8
9
Object success = Either.right("value")
.right()
.getOrElse("defaultValue");
assertEquals("value", success);

Object fail = Either.left("error")
.right()
.getOrElse("defaultValue");
assertEquals("defaultValue", fail);
   /