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));
}
詳細については、次のブログ記事を参照してください: Towards Pattern Matching in Java .
この質問はすでに回答済みであることを認識しています。さらに、私は関数型プログラミングは初めてですが、多くの躊躇の後、最終的にこのディスカッションに参加して、次の内容についてフィードバックを得ることにしました。
以下の(あまりにも?)単純な実装をお勧めします。受け入れられた回答で引用されている(素敵な)記事とは少し異なります。しかし、私の(短い)経験では、使用するのがもう少し柔軟で、保守が簡単でした(もちろん、これも好みの問題です)。
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Predicate;
final class Test
{
public static final Function<Integer, Integer> fact = new Match<Integer>()
.caseOf( i -> i == 0, i -> 1 )
.otherwise( i -> i * Test.fact.apply(i - 1) );
public static final Function<Object, String> dummy = new Match<Object>()
.caseOf( i -> i.equals(42), i -> "forty-two" )
.caseOf( i -> i instanceof Integer, i -> "Integer : " + i.toString() )
.caseOf( i -> i.equals("world"), i -> "Hello " + i.toString() )
.otherwise( i -> "got this : " + i.toString() );
public static void main(String[] args)
{
System.out.println("factorial : " + fact.apply(6));
System.out.println("dummy : " + dummy.apply(42));
System.out.println("dummy : " + dummy.apply(6));
System.out.println("dummy : " + dummy.apply("world"));
System.out.println("dummy : " + dummy.apply("does not match"));
}
}
final class Match<T>
{
public <U> CaseOf<U> caseOf(Predicate<T> cond, Function<T, U> map)
{
return this.new CaseOf<U>(cond, map, Optional.empty());
}
class CaseOf<U> implements Function<T, Optional<U>>
{
private Predicate<T> cond;
private Function<T, U> map;
private Optional<CaseOf<U>> previous;
CaseOf(Predicate<T> cond, Function<T, U> map, Optional<CaseOf<U>> previous)
{
this.cond = cond;
this.map = map;
this.previous = previous;
}
@Override
public Optional<U> apply(T value)
{
Optional<U> r = previous.flatMap( p -> p.apply(value) );
return r.isPresent() || !cond.test(value) ? r
: Optional.of( this.map.apply(value) );
}
public CaseOf<U> caseOf(Predicate<T> cond, Function<T, U> map)
{
return new CaseOf<U>(cond, map, Optional.of(this));
}
public Function<T,U> otherwise(Function<T, U> map)
{
return value -> this.apply(value)
.orElseGet( () -> map.apply(value) );
}
}
}