Java 8 模式匹配?
Java 8会像Scala和其他函数程序那样支持模式匹配吗?我正在将Java 8的Lambda功能放在一起。我找不到任何关于这个特定的函数式编程概念的东西。
我记得让我对函数式编程感兴趣的是快速排序实现,特别是与命令式编程的实现相比。
Java 8会像Scala和其他函数程序那样支持模式匹配吗?我正在将Java 8的Lambda功能放在一起。我找不到任何关于这个特定的函数式编程概念的东西。
我记得让我对函数式编程感兴趣的是快速排序实现,特别是与命令式编程的实现相比。
我想你不是在谈论在字符串上应用正则表达式的模式匹配,而是在Haskell中应用的那样。例如,使用通配符:
head (x:_) = x
tail (_:xs) = xs
Java 8本身不会支持这一点,但是,对于Lambda表达式,有一些方法可以做到这一点,例如用于计算阶乘:
public static int fact(int n) {
return ((Integer) new PatternMatching(
inCaseOf(0, _ -> 1),
otherwise( _ -> n * fact(n - 1))
).matchFor(n));
}
如何实现这一点,您将在此博客文章中找到更多信息:在Java中实现模式匹配。
在Java 8中,可以将模式匹配实现为库(利用lambda表达式),但不幸的是,我们仍然会缺少Haskell或Scala等语言的编译器穷举检查。
Cyclops-react有一个强大的模式匹配模块,它既为Java 8提供结构模式匹配,也通过保护提供模式匹配。
它提供了一个当/然后/否则DSL和匹配,包括解构是基于标准的Java谓词(所以匹配可以用来过滤流的例子)。
对于通过防护装置进行匹配,我们使用 whenGuard / then / 否则来清楚地显示情况是驱动测试,而不是被测对象的结构。
例如,对于基于防护的匹配,如果我们实现一个实现可匹配接口的Case类
static class MyCase implements Matchable{ int a; int b; int c;}
(顺便说一句,龙目岛可以非常方便地创建密封的案例类层次结构)
我们可以匹配它的内部值(如有必要,可以递归,也可以在各种其他选项中按类型进行匹配)。
import static com.aol.cyclops.control.Matchable.otherwise;
import static com.aol.cyclops.control.Matchable.whenGuard;
new MyCase(1,2,3).matches(c->c.is(whenGuard(1,2,3)).then("hello"),
.is(whenGuard(4,5,6)).then("goodbye")
,otherwise("goodbye")
);
如果我们有一个对象没有实现[Matchable][3],我们无论如何都可以强制它为Matchable,我们的代码会变成
Matchable.ofDecomposable(()->new MyCase(1,2,3)))
.matches(c->c.is(whenGuard(1,2,3)).then("hello"),
.is(whenGuard(4,5,6)).then("goodbye")
,otherwise("hello"));
如果我们不关心其中一个值,我们可以使用通配符
new MyCase(1,2,3).matches(c->c.is(whenGuard(1,__,3)).then("hello"),
.is(whenGuard(4,__,6)).then("goodbye")
,otherwise("hello)
);
或者以递归方式解构一组嵌套的类
Matchable.of(new NestedCase(1,2,new NestedCase(3,4,null)))
.matches(c->c.is(whenGuard(1,__,has(3,4,__)).then("2")
,otherwise("default");
其中 NestedCase 看起来像这样 -
class NestedCase implemends Decomposable { int a; int b; NestedCase c; }
用户还可以使用 hamcrest 编写模式匹配表达式
import static com.aol.cyclops.control.Matchable.otherwise;
import static com.aol.cyclops.control.Matchable.then;
import static com.aol.cyclops.control.Matchable.when;
Matchable.of(Arrays.asList(1,2,3))
.matches(c->c.is(when(equalTo(1),any(Integer.class),equalTo(4)))
.then("2"),otherwise("default"));
我们还可以匹配被测对象的确切结构。也就是说,与其使用 if/then 测试来查看结构是否恰好与我们的情况匹配,不如让编译器确保我们的情况与所提供对象的结构相匹配。这样做的DSL与基于防护的匹配几乎相同,但是我们使用当/then /否则清楚地显示对象结构驱动测试用例,反之亦然。
import static com.aol.cyclops.control.Matchable.otherwise;
import static com.aol.cyclops.control.Matchable.then;
import static com.aol.cyclops.control.Matchable.when;
String result = new Customer("test",new Address(10,"hello","my city"))
.match()
.on$_2()
.matches(c->c.is(when(decons(when(10,"hello","my city"))),then("hello")), otherwise("miss")).get();
//"hello"
从客户提取的地址对象在结构上匹配。客户和地址类在哪里看起来这个
@AllArgsConstructor
static class Address{
int house;
String street;
String city;
public MTuple3<Integer,String,String> match(){
return Matchable.from(()->house,()->street,()->city);
}
}
@AllArgsConstructor
static class Customer{
String name;
Address address;
public MTuple2<String,MTuple3<Integer,String,String>> match(){
return Matchable.from(()->name,()->Maybe.ofNullable(address).map(a->a.match()).orElseGet(()->null));
}
}
cyclops-react 提供了一个 Matchables 类,该类允许针对常见 JDK 类型的结构模式匹配。