こんにちは。アプリ開発担当です。 以前手続き型と関数型の違いについて実際にコードを書きました。社内のエンジニアから続編を要望されたので、テーマを変えてまた書いてみたいとおもいます。今回のテーマはFizzBuzzです。
今回はJava11、標準ライブラリで書きました。
void fizzbuzz1() { println("* fizzbuzz1()"); for (var i = 1; i <= 100; i++) { if (i % 15 == 0) { println("FizzBuzz"); } else if (i % 3 == 0) { println("Fizz"); } else if (i % 5 == 0) { println("Buzz"); } else { println(i); } } }
void fizzbuzz2() { println("* fizzbuzz2()"); for (var i = 1; i <= 100; i++) { var s = ""; if (i % 3 == 0) { s += "Fizz"; } if (i % 5 == 0) { s += "Buzz"; } if (s.isEmpty()) { s += i; } println(s); } }
void fizzbuzz3() { println("* fizzbuzz3()"); var d = Map.of(3, "Fizz", 5, "Buzz", 15, "FizzBuzz"); for (var i = 1; i <= 100; i++) { var b1 = BigInteger.valueOf(i); var b2 = BigInteger.valueOf(15); var gcd = b1.gcd(b2); println(d.getOrDefault(gcd.intValue(), Integer.toString(i))); } }
関数型だと、例えばこのように。
boolean isFizz(int n) { return n % 3 == 0; } boolean isBuzz(int n) { return n % 5 == 0; } boolean isFizzBuzz(int n) { return n % 15 == 0; } String asFizzBuzz(int n) { return isFizzBuzz(n) ? "FizzBuzz" : isFizz(n) ? "Fizz" : isBuzz(n) ? "Buzz" : Integer.toString(n); } void fp_fizzbuzz1() { println("* fp_fizzbuzz1()"); IntStream.rangeClosed(1, 100) .mapToObj(this::asFizzBuzz) .forEach(this::println); }
int increment(int n) { return n + 1; } void fp_fizzbuzz2() { println("* fp_fizzbuzz2()"); var res = Stream.iterate(1, this::increment) .map(this::asFizzBuzz) .limit(100) .collect(Collectors.joining(System.lineSeparator())); println(res); } String combineLines(String a, String b) { return a + System.lineSeparator() + b; }
void fp_fizzbuzz3() { println("* fp_fizzbuzz3()"); Stream.iterate(1, this::increment) .map(this::asFizzBuzz) .limit(100) .reduce(this::combineLines) .ifPresent(this::println); }
いかがでしょう。 考え方、捉え方によって書き方は一通りではない、ということですね。簡単な動作の方が手軽に様々な書き方を試せるとおもいます。まだ関数型に慣れてない人は、このような簡単なものから始めた方がいいかもしれません。
関数型のほうが汎用性が高くなったり、複雑な処理も簡潔にかけるので便利なことが多いです。ただ処理スピードは手続き型の方が速いため、やむを得ず手続き型を使う場面もあります。また、実際の開発の場面では、関数型だけで実装できることは少なく、手続き型と併用して使用するケースがほとんどです。
重要なのは、要件や開発環境に合わせて適切に使えるということですね。
ただ、私は関数型が大好きです。
合わせて高階関数についても作成したので、そちらはいつか記事にしたいとおもいます。
※ iChainでは一緒に働く仲間を募集しています。よかったらHPとかwantedlyとかみて、是非応募ください!