Java 8模式匹配?

eda*_*oyo 29 java lambda matching java-8

Java 8是否支持像Scala和其他功能程序一样的模式匹配?我正在一起介绍Java 8的Lambda功能.我在这个特定的功能编程概念上找不到任何东西.

我记得让我对函数式编程感兴趣的是quicksort实现,特别是与命令式编程的实现相比.

Kon*_*che 30

我想你不是在谈论在字符串上应用正则表达式的模式匹配,而是在Haskell中应用.例如,使用通配符:

head (x:_)  = x
tail (_:xs) = xs
Run Code Online (Sandbox Code Playgroud)

Java 8将不支持本机,但Lambda表达式有这样的方法,比如计算阶乘:

public static int fact(int n) {
     return ((Integer) new PatternMatching(
          inCaseOf(0, _ -> 1),
          otherwise(  _ -> n * fact(n - 1))
     ).matchFor(n));
}
Run Code Online (Sandbox Code Playgroud)

如何实现您将在此博客文章中找到更多信息:在Java中进行模式匹配.


Joh*_*ean 10

可以在Java 8中实现模式匹配作为库(利用lambda表达式),但不幸的是,我们仍然会遗漏编译器穷举检查Haskell或Scala等语言.

Cyclops-react有一个强大的模式匹配 模块,它为Java 8提供结构模式匹配,并通过保护提供模式匹配.

它提供了何时/当/其他DSL和匹配,包括解构基于标准Java Predicates(因此匹配可用于过滤流,例如).

由卫兵匹配

对于匹配的防护,我们使用whenGuard/then/otherwise来清楚地显示案例正在驱动测试而不是被测对象的结构.

例如,对于基于防护的匹配,如果我们实现一个实现Matchable接口的Case类

 static class MyCase  implements Matchable{ int a; int b; int c;}
Run Code Online (Sandbox Code Playgroud)

(顺便说一句,Lombok可以非常方便地创建密封的案例类层次结构)

我们可以匹配它的内部值(如果需要,可以递归,或者通过各种其他选项之间的类型).

  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")
                           );
Run Code Online (Sandbox Code Playgroud)

如果我们有一个没有实现[Matchable] [3]的Object,我们可以将它强制转换为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"));
Run Code Online (Sandbox Code Playgroud)

如果我们不关心其中一个值,我们可以使用通配符

new MyCase(1,2,3).matches(c->c.is(whenGuard(1,__,3)).then("hello"),
                              .is(whenGuard(4,__,6)).then("goodbye")
                              ,otherwise("hello)
                           );
Run Code Online (Sandbox Code Playgroud)

或者递归地解构一组嵌套的类

Matchable.of(new NestedCase(1,2,new NestedCase(3,4,null)))
                .matches(c->c.is(whenGuard(1,__,has(3,4,__)).then("2")
                 ,otherwise("default");
Run Code Online (Sandbox Code Playgroud)

NestedCase看起来像这样 -

class NestedCase implemends Decomposable { int a; int b; NestedCase c; }
Run Code Online (Sandbox Code Playgroud)

用户还可以使用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"));
Run Code Online (Sandbox Code Playgroud)

结构模式匹配

我们还可以匹配被测试对象的确切结构.那不是使用if/then测试结果是否恰好匹配我们的情况,我们可以让编译器确保我们的情况与提供的对象的结构相匹配.执行此操作的DSL几乎与基于防护的匹配相同,但我们使用when/then/otherwise来清楚地显示对象结构驱动测试用例而不是相反.

  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"
Run Code Online (Sandbox Code Playgroud)

在结构上匹配从客户提取的地址对象.客户和地址类看起来如此

@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));
    }
}
Run Code Online (Sandbox Code Playgroud)

cyclops-react提供了一个Matchables类,它允许对常见的JDK类型进行结构模式匹配.