Java関数式プログラミング(10)文字列およびメソッド参照

7018 ワード

このシリーズの文章はVenkat Subramaniamの
Functional Programming in Java
未完は続きますが、引き続き[url={{site.url}]Java翻訳ステーション[/url]に注目してください.
第3章文字列、比較器、フィルタ
JDKが導入したいくつかの方法は関数スタイルのコードを書くのに役立つ.JDKライブラリのいくつかのクラスとインタフェースは、Stringなど、以前の習慣から抜け出すためによく使われています.
古いスタイルでは、これらの新しい方法を使用する機会を積極的に探さなければなりません.同様に、匿名の内部クラスを1つの方法で使用する必要がある場合、lambda式で置き換えることができます.
ああ、元のように書くほど煩わしいことはありません.
この章では、lambda式とメソッドリファレンスを使用して文字列を巡回し、Comparatorインタフェースを実装し、ディレクトリ内のファイルを表示し、ファイルとディレクトリの変更を監視します.前章で紹介した方法
また、これらのタスクをよりよく完了するために、ここに引き続き表示されます.これらの新しいテクノロジーは、冗長で煩雑なコードを簡潔にするのに役立ち、迅速に実現できるだけでなく、メンテナンスも容易です.
遍歴文字列
chars()メソッドはStringクラスの新しいメソッドであり,CharSequenceインタフェースの一部である.Stringの文字列をすばやく巡回するには、便利なツールです.この>内部反復器があれば、文字列の各文字を簡単に操作できます.まず文字列を処理してみましょう.ここではついでに方法の引用のいくつかの使い方を紹介します.
{% highlight java %}
final String str = "w00t";
str.chars()
     .forEach(ch -> System.out.println(ch));
{% endhighlight %}
chars()メソッドはStreamオブジェクトを返し,その内部反復器forEach()で遍歴できる.反復器では、文字列の文字に直接アクセスできます.次は
文字列を巡回し、各文字の出力結果を印刷します.
{% highlight java %}
"_posts/2014-03-30-java-functional-programming-10.markdown"146L, 8327C written
[root@AY140109200406026f46Z kunka]# ./generate.sh
Configuration file:/root/kunka/_config.yml
            Source:/root/kunka
       Destination:/usr/share/nginx/html/
      Generating... done.
[root@AY140109200406026f46Z kunka]# ./convert_iteye.sh
---
layout: post
title:Java関数式プログラミング(10)文字列およびメソッド参照
date: 2014-03-30 08:53:31
category:Java関数プログラミング
keywords:メソッドリファレンス
---
このシリーズの文章はVenkat Subramaniamの
Functional Programming in Java
未完は続きますので、後続の文章に引き続きご注目ください
Java翻訳ステーション .
第三章文字列、比較器とフィルタ
JDKが導入したいくつかの方法は関数スタイルのコードを書くのに役立つ.JDKライブラリのいくつかのクラスとインタフェースは私たちがよく知っています.例えば、Stringは、以前慣れていた古いスタイルから抜け出すために、私たちは自分からこれらの新しい方法を使う機会を探さなければなりません.同様に、匿名の内部クラスを1つの方法で使用する必要がある場合、lambda式で置き換えることができ、元のように書くほど煩雑ではありません.
この章では、lambda式とメソッドリファレンスを使用して文字列を巡回し、Comparatorインタフェースを実装し、ディレクトリ内のファイルを表示し、ファイルとディレクトリの変更を監視します.前章で説明したいくつかの方法は、これらのタスクをよりよく完了するのに役立ちます.これらの新しいテクノロジーは、冗長で煩雑なコードを簡潔にするのに役立ち、迅速に実現できるだけでなく、メンテナンスも容易です.
遍歴文字列
chars()メソッドはStringクラスの新しいメソッドであり,CharSequenceインタフェースの一部である.Stringの文字列をすばやく巡回するには、便利なツールです.この内部反復器があれば、文字列の各文字を簡単に操作できます.まず文字列を処理してみましょう.ここではついでに方法の引用のいくつかの使い方を紹介します.

final String str = "w00t";
str.chars()
     .forEach(ch -> System.out.println(ch));

chars()メソッドはStreamオブジェクトを返し,その内部反復器forEach()で遍歴できる.反復器では、文字列の文字に直接アクセスできます.次に、文字列を巡回し、各文字の出力結果を印刷します.

119
48
48
116

これは私たちが望んでいる結果ではありません.私たちが見たいのはアルファベットで、出力は数字です.これはchars()メソッドが文字型ではなく整数型のStreamを返すためである.このAPIを理解してから、出力の結果を最適化します.
前のコードではforEachメソッドのパラメータとしてlambda式を作成しました.パラメータをprintln()メソッドに簡単に渡しただけです.この操作は一般的であるため、Javaコンパイラを使用してこのコードを簡略化することができます.25ページの
メソッドリファレンスでは、代わりにメソッドリファレンスを使用して、コンパイラにパラメータルーティングを手伝ってもらいます.
インスタンスメソッドのメソッドリファレンスを作成する方法について説明しました.たとえば、name.toUpperCase()メソッドは、String::toUpperCaseを参照します.次の例では、静的参照System.outのインスタンスメソッドを呼び出します.メソッドが参照する2つのコロンの左側には、クラス名または式があります.この柔軟性により、以下のようにprintln()メソッドの参照を簡単に作成できます.

str.chars()
     .forEach(System.out::println);

Javaコンパイラはパラメータのルーティングをスマートに完了できることがわかります.思い出すとlambda式とメソッドリファレンスは関数式インタフェースを受信する場所にしか現れず、Javaコンパイラはその場所で対応するメソッドを生成します(訳注:コンパイラは関数式インタフェースの実装を生成し、この実装は1つのメソッドしかありません).以前に使用した方法はString::toUpperCaseを参照し、その生成方法のパラメータに伝え、最後にこの方法で呼び出されたターゲットオブジェクトになります.このようにparameter.toUpperCase()です.これは、このメソッドリファレンスがクラス名(String)に基づいているためです.この例のメソッドリファレンスは、PrintStreamのインスタンスであり、System.outで参照される式に基づいています.メソッド呼び出しのオブジェクトが既に存在するため、Javaコンパイラは、生成メソッドのパラメータをこのprintlnメソッドのパラメータとして使用することを決定します.System.out.println(name).
(注:実は主に2つのシーンで、同じように1つのメソッドリファレンスが渡されています.1つは遍歴したオブジェクトで、もちろんメソッド呼び出しのターゲットオブジェクト、例えばname.toUpperCase、もう1つはメソッド呼び出しのパラメータとして、例えばSystem.out.println(name).
メソッドリファレンスを使用するとコードが簡潔になりますが、どのように動作しているのかを深く理解しなければなりません.メソッドリファレンスを熟知すれば、パラメータルーティングを自分で理解することができます.
この例のコードは簡潔ですが、出力はあまりよくありません.アルファベットの結果に数字が現れたのを見たいです.この問題を解決するために、intをアルファベットに出力する方法を書きます.

private static void printChar(int aChar) {
      System.out.println((char)(aChar));
}

メソッドリファレンスを使用すると、出力結果の最適化を容易に完了できます.

str.chars()
     .forEach(IterateString::printChar);

今chars()が返した結果はintですが、どうでもいいので、印刷が必要なときは文字に変換します.今回の出力はやっとアルファベットです.

w
0
0
t

最初からintではなく文字を処理したい場合は、charsを呼び出した後、intを直接文字に変換できます.

str.chars()
     .mapToObj(ch -> Character.valueOf((char)ch))
     .forEach(System.out::println);

ここではchars()が返すStreamの内部反復器を使用しました.もちろん、この方法だけではありません.Streamオブジェクトを手に入れると、map()、filter()、reduce()など、私たちの使用に任せます.filter()メソッドを使用して、数字の文字をフィルタできます.

str.chars()
     .filter(ch -> Character.isDigit(ch))
     .forEach(ch -> printChar(ch));

このように出力すると、数字しか見えません.

0
0

同様に、lambda式をfilter()メソッドとforEach()メソッドに渡すほか、メソッドリファレンスも使用できます.

str.chars()
     .filter(Character::isDigit)
     .forEach(IterateString::printChar);

ここでのメソッドリファレンスは、余分なパラメータを省略します.この例では、前の2つのメソッドのリファレンスとは異なる使い方も見られます.最初にリファレンスしたのはインスタンスメソッドで、2回目は静的リファレンス(System.out)上のメソッドです.今回は静的メソッドのリファレンスです.メソッドリファレンスは黙々と払われています.
インスタンスメソッドと静的メソッドの参照は同じように見えます.たとえばString::toUpperCaseとCharacter::isDigitです.コンパイラは、メソッドがインスタンスメソッドか静的メソッドかを判断し、パラメータのルーティング方法を決定します.インスタンスメソッドの場合、parameter、toUpperCase()などのメソッド呼び出しのターゲットオブジェクトとして生成メソッドのパラメータが使用されます.(もちろん例外もありますが、例えばメソッド呼び出しのターゲットオブジェクトがSystem::out.println()のように指定されています.また、静的メソッドであれば、生成メソッドのパラメータは、Character.isDigit(parameter)のように、この参照メソッドのパラメータとして使用されます.152ページの付録2には、詳細なメソッド参照の使用方法および構文の説明があります.
メソッドの参照は便利ですが、メソッドの名前の競合による二義性という問題があります.一致するメソッドにはインスタンスメソッドと静的メソッドがあり、メソッドに曖昧なコンパイラがあるためエラーが報告されます.たとえば、Double::toStringといえば、doubleタイプを文字列に変換したいのですが、コンパイラはそれが何なのか分かりません.public String toString()のインスタンスメソッドを呼び出すか、public static String toString(double)メソッドを呼び出すか.両方のメソッドがDoubleクラスなので.このような状況に遭遇したら、がっかりしないで、lambda式で完成すればいい.
関数プログラミングに適応すると,lambda式と方法参照の間を自由に切り替えることができる.
このセクションでは、Java 8の新しいメソッドを使用して文字列を巡回します.次に、Comparatorインタフェースの改善点を見てみましょう.
未完は続きますので、後続の文章に引き続きご注目ください
Java翻訳ステーション .
オリジナル記事の転載は出典を明記してください.
http://it.deepinmind.com