【Javaベース】:JavaのLambda式適用
91585 ワード
1.はじめに
最近Flinkのソースコードを研究して、中に多くのLambda式があることを発見して、いくつかの用法はまだそんなにはっきりしていないで、すべて専門的に資料を調べて、JavaのLambda式の応用に対していくつか総括を行います.Lambda式はJava SE 8の中で1つの重要な新しい特性です.Lambda式では、機能インタフェースの代わりに式を使用できます.Lambda式は、メソッドと同様に、通常のパラメータリストと、これらのパラメータを使用するボディ(body、式またはコードブロック)を提供します.Lambda式は集合ライブラリも強化した.Java SE 8には、集合データを一括操作するパッケージとしてjava.util.functionパッケージとjava.util.streamパッケージの2つが追加されています.ストリーム(stream)は反復器(iterator)のようなものですが、多くの追加機能が付加されています.総じてlambda式とstreamはJava言語に汎用(Generics)と注釈(annotation)を追加して以来最大の変化である.本稿では,lambda式とstreamの強さを認識する単純から複雑な例を参照する.環境準備Java 8がまだインストールされていない場合は、lambdaとstreamを使用する前にインストールする必要があります(翻訳者は仮想マシンにインストールし、テストして使用することをお勧めします).NetBeansやIntelliJ IDEAのようなツールやIDEは、lambda式、重複可能な注釈、コンパクトなプロファイル、その他の特性を含むJava 8特性をサポートします.Java SE 8とNetBeans IDE 8のダウンロードリンクは、Java Platform(JDK 8):OracleからJava 8をダウンロードするか、NetBeans IDEとともにNetBeans IDEをダウンロードできます8:NetBeans公式サイトからNetBeans IDE Lambda式の構文基本構文をダウンロードします:(parameters)->expressionまたは(parameters)->statements;}
2.使用例
Java lambda式の簡単な例を次に示します.
基本的なLambdaの例
今、lambda式とは何かを知っています.まず、いくつかの基本的な例から始めましょう.このセクションでは、lambda式が私たちの符号化方法にどのように影響するかを示します.プレイヤーリストがあると仮定すると、プログラマーはfor文(「forループ」)を使って巡回することができ、Java SE 8で別の形式に変換することができる.
ご覧のように、lambda式は私たちのコードを1行に縮小することができます.もう1つの例は、グラフィックユーザインタフェースプログラムでは、匿名クラスをlambda式で置き換えることができる.同様に、Runnableインタフェースを実装する際にも、次のように使用できます.
次に、lambdasを使用してRunnableインタフェースを実装する例を示します.
Runnableのlambda式は、ブロックフォーマットを使用して5行のコードを1行の文に変換します.次に、次のセクションではlambdasを使用してコレクションをソートします.
Lambdasを使用してコレクションをソートする
Javaでは、Comparatorクラスがセットをソートするために使用されます.次の例では、選手のname、surname、nameの長さ、最後のアルファベットに基づいています.前の例と同様に、匿名の内部クラスを使用してソートし、lambda式を使用してコードを簡略化します.最初の例では、nameに基づいてlistをソートします.古い方法では、コードは次のようになります.
Lambdasを使用すると、次のコードで同じ機能を実現できます.
その他のソートは以下の通りです.上記の例と同様に、コードは匿名の内部クラスといくつかのlambda式によってComparatorを実現します.
このように、簡潔で直感的です.次のセクションでは、より多くのlambdasの能力を探求し、streamと組み合わせて使用します.
LambdasとStreamsの使用
Streamは集合のパッケージで、通常はlambdaと一緒に使用されます.lambdasを使用すると、map、filter、limit、sorted、count、min、max、sum、collectなど、多くの操作をサポートできます.同様に、Streamは怠け者の演算を使用しており、実際にすべてのデータを読み取ることはなく、getFirst()のような方法でチェーン構文を終了します.次の例では、lambdasとstreamsが何ができるかを探索します.Personクラスを作成し、listにデータを追加するためにこのクラスを使用し、さらなるストリーム操作に使用します.Personは単純なPOJOクラスにすぎません.
次に、Personオブジェクトを格納するために2つのlistを作成します.
forEachメソッドを使用して、上記のリストを反復出力します.
私たちはforEachメソッドを使用して、プログラマーの給料を5%増やします.
もう1つの有用な方法はフィルタフィルタ()で、月給が1400ドルを超えるPHPプログラマーを表示します.
フィルタを定義し、再利用して他の操作を実行することもできます.
limitメソッドを使用すると、結果セットの数を制限できます.
ソートは?streamで処理できますか?答えは肯定的だ.次の例では、Javaプログラマーを名前と給与に基づいてソートし、リストに配置してリストを表示します.
最低賃金と最高賃金だけに興味がある場合は、ソート後に最初の/最後の1つを選択するよりも速いのはminとmaxの方法です.
上記の例ではcollectメソッドがどのように動作しているかを示しています.mapメソッドと組み合わせて、collectメソッドを使用して、結果セットを文字列、Set、またはTreeSetに配置できます.
Streamsはパラレル(parallel)でもよい.例は次のとおりです.
summaryStatistics法を用いてstream中の要素の様々な要約データを得ることができる.次に、getMax、getMin、getSum、getAverageなどの方法にアクセスします.
3.まとめ
これらの操作はFlinkのチェーン操作と似ているかどうか.
リファレンス https://www.cnblogs.com/franson-2016/p/5593080.html
最近Flinkのソースコードを研究して、中に多くのLambda式があることを発見して、いくつかの用法はまだそんなにはっきりしていないで、すべて専門的に資料を調べて、JavaのLambda式の応用に対していくつか総括を行います.Lambda式はJava SE 8の中で1つの重要な新しい特性です.Lambda式では、機能インタフェースの代わりに式を使用できます.Lambda式は、メソッドと同様に、通常のパラメータリストと、これらのパラメータを使用するボディ(body、式またはコードブロック)を提供します.Lambda式は集合ライブラリも強化した.Java SE 8には、集合データを一括操作するパッケージとしてjava.util.functionパッケージとjava.util.streamパッケージの2つが追加されています.ストリーム(stream)は反復器(iterator)のようなものですが、多くの追加機能が付加されています.総じてlambda式とstreamはJava言語に汎用(Generics)と注釈(annotation)を追加して以来最大の変化である.本稿では,lambda式とstreamの強さを認識する単純から複雑な例を参照する.環境準備Java 8がまだインストールされていない場合は、lambdaとstreamを使用する前にインストールする必要があります(翻訳者は仮想マシンにインストールし、テストして使用することをお勧めします).NetBeansやIntelliJ IDEAのようなツールやIDEは、lambda式、重複可能な注釈、コンパクトなプロファイル、その他の特性を含むJava 8特性をサポートします.Java SE 8とNetBeans IDE 8のダウンロードリンクは、Java Platform(JDK 8):OracleからJava 8をダウンロードするか、NetBeans IDEとともにNetBeans IDEをダウンロードできます8:NetBeans公式サイトからNetBeans IDE Lambda式の構文基本構文をダウンロードします:(parameters)->expressionまたは(parameters)->statements;}
2.使用例
Java lambda式の簡単な例を次に示します.
// 1. , 5
() -> 5
// 2. ( ), 2
x -> 2 * x
// 3. 2 ( ),
(x, y) -> x – y
// 4. 2 int ,
(int x, int y) -> x + y
// 5. string , , ( void)
(String s) -> System.out.print(s)
基本的なLambdaの例
今、lambda式とは何かを知っています.まず、いくつかの基本的な例から始めましょう.このセクションでは、lambda式が私たちの符号化方法にどのように影響するかを示します.プレイヤーリストがあると仮定すると、プログラマーはfor文(「forループ」)を使って巡回することができ、Java SE 8で別の形式に変換することができる.
String[] atp = {"Rafael Nadal", "Novak Djokovic",
"Stanislas Wawrinka",
"David Ferrer","Roger Federer",
"Andy Murray","Tomas Berdych",
"Juan Martin Del Potro"};
List<String> players = Arrays.asList(atp);
//
for (String player : players) {
System.out.print(player + "; ");
}
// lambda (functional operation)
players.forEach((player) -> System.out.print(player + "; "));
// Java 8 (double colon operator)
players.forEach(System.out::println);
ご覧のように、lambda式は私たちのコードを1行に縮小することができます.もう1つの例は、グラフィックユーザインタフェースプログラムでは、匿名クラスをlambda式で置き換えることができる.同様に、Runnableインタフェースを実装する際にも、次のように使用できます.
//
btn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
System.out.println("Hello World!");
}
});
// lambda expression
btn.setOnAction(event -> System.out.println("Hello World!"));
次に、lambdasを使用してRunnableインタフェースを実装する例を示します.
// 1.1
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Hello world !");
}
}).start();
// 1.2 lambda expression
new Thread(() -> System.out.println("Hello world !")).start();
// 2.1
Runnable race1 = new Runnable() {
@Override
public void run() {
System.out.println("Hello world !");
}
};
// 2.2 lambda expression
Runnable race2 = () -> System.out.println("Hello world !");
// run ( !)
race1.run();
race2.run();
Runnableのlambda式は、ブロックフォーマットを使用して5行のコードを1行の文に変換します.次に、次のセクションではlambdasを使用してコレクションをソートします.
Lambdasを使用してコレクションをソートする
Javaでは、Comparatorクラスがセットをソートするために使用されます.次の例では、選手のname、surname、nameの長さ、最後のアルファベットに基づいています.前の例と同様に、匿名の内部クラスを使用してソートし、lambda式を使用してコードを簡略化します.最初の例では、nameに基づいてlistをソートします.古い方法では、コードは次のようになります.
String[] players = {"Rafael Nadal", "Novak Djokovic",
"Stanislas Wawrinka", "David Ferrer",
"Roger Federer", "Andy Murray",
"Tomas Berdych", "Juan Martin Del Potro",
"Richard Gasquet", "John Isner"};
// 1.1 name players
Arrays.sort(players, new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return (s1.compareTo(s2));
}
});
Lambdasを使用すると、次のコードで同じ機能を実現できます.
// 1.2 lambda expression players
Comparator<String> sortByName = (String s1, String s2) -> (s1.compareTo(s2));
Arrays.sort(players, sortByName);
// 1.3 :
Arrays.sort(players, (String s1, String s2) -> (s1.compareTo(s2)));
その他のソートは以下の通りです.上記の例と同様に、コードは匿名の内部クラスといくつかのlambda式によってComparatorを実現します.
// 1.1 surname players
Arrays.sort(players, new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return (s1.substring(s1.indexOf(" ")).compareTo(s2.substring(s2.indexOf(" "))));
}
});
// 1.2 lambda expression , surname
Comparator<String> sortBySurname = (String s1, String s2) ->
( s1.substring(s1.indexOf(" ")).compareTo( s2.substring(s2.indexOf(" ")) ) );
Arrays.sort(players, sortBySurname);
// 1.3 , , ...
Arrays.sort(players, (String s1, String s2) ->
( s1.substring(s1.indexOf(" ")).compareTo( s2.substring(s2.indexOf(" ")) ) )
);
// 2.1 name lenght players
Arrays.sort(players, new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return (s1.length() - s2.length());
}
});
// 2.2 lambda expression , name lenght
Comparator<String> sortByNameLenght = (String s1, String s2) -> (s1.length() - s2.length());
Arrays.sort(players, sortByNameLenght);
// 2.3 or this
Arrays.sort(players, (String s1, String s2) -> (s1.length() - s2.length()));
// 3.1 players,
Arrays.sort(players, new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return (s1.charAt(s1.length() - 1) - s2.charAt(s2.length() - 1));
}
});
// 3.2 lambda expression ,
Comparator<String> sortByLastLetter =
(String s1, String s2) ->
(s1.charAt(s1.length() - 1) - s2.charAt(s2.length() - 1));
Arrays.sort(players, sortByLastLetter);
// 3.3 or this
Arrays.sort(players, (String s1, String s2) -> (s1.charAt(s1.length() - 1) - s2.charAt(s2.length() - 1)));
このように、簡潔で直感的です.次のセクションでは、より多くのlambdasの能力を探求し、streamと組み合わせて使用します.
LambdasとStreamsの使用
Streamは集合のパッケージで、通常はlambdaと一緒に使用されます.lambdasを使用すると、map、filter、limit、sorted、count、min、max、sum、collectなど、多くの操作をサポートできます.同様に、Streamは怠け者の演算を使用しており、実際にすべてのデータを読み取ることはなく、getFirst()のような方法でチェーン構文を終了します.次の例では、lambdasとstreamsが何ができるかを探索します.Personクラスを作成し、listにデータを追加するためにこのクラスを使用し、さらなるストリーム操作に使用します.Personは単純なPOJOクラスにすぎません.
public class Person {
private String firstName, lastName, job, gender;
private int salary, age;
public Person(String firstName, String lastName, String job,
String gender, int age, int salary) {
this.firstName = firstName;
this.lastName = lastName;
this.gender = gender;
this.age = age;
this.job = job;
this.salary = salary;
}
// Getter and Setter
// . . . . .
}
次に、Personオブジェクトを格納するために2つのlistを作成します.
List<Person> javaProgrammers = new ArrayList<Person>() {
{
add(new Person("Elsdon", "Jaycob", "Java programmer", "male", 43, 2000));
add(new Person("Tamsen", "Brittany", "Java programmer", "female", 23, 1500));
add(new Person("Floyd", "Donny", "Java programmer", "male", 33, 1800));
add(new Person("Sindy", "Jonie", "Java programmer", "female", 32, 1600));
add(new Person("Vere", "Hervey", "Java programmer", "male", 22, 1200));
add(new Person("Maude", "Jaimie", "Java programmer", "female", 27, 1900));
add(new Person("Shawn", "Randall", "Java programmer", "male", 30, 2300));
add(new Person("Jayden", "Corrina", "Java programmer", "female", 35, 1700));
add(new Person("Palmer", "Dene", "Java programmer", "male", 33, 2000));
add(new Person("Addison", "Pam", "Java programmer", "female", 34, 1300));
}
};
List<Person> phpProgrammers = new ArrayList<Person>() {
{
add(new Person("Jarrod", "Pace", "PHP programmer", "male", 34, 1550));
add(new Person("Clarette", "Cicely", "PHP programmer", "female", 23, 1200));
add(new Person("Victor", "Channing", "PHP programmer", "male", 32, 1600));
add(new Person("Tori", "Sheryl", "PHP programmer", "female", 21, 1000));
add(new Person("Osborne", "Shad", "PHP programmer", "male", 32, 1100));
add(new Person("Rosalind", "Layla", "PHP programmer", "female", 25, 1300));
add(new Person("Fraser", "Hewie", "PHP programmer", "male", 36, 1100));
add(new Person("Quinn", "Tamara", "PHP programmer", "female", 21, 1000));
add(new Person("Alvin", "Lance", "PHP programmer", "male", 38, 1600));
add(new Person("Evonne", "Shari", "PHP programmer", "female", 40, 1800));
}
};
forEachメソッドを使用して、上記のリストを反復出力します.
System.out.println(" :");
javaProgrammers.forEach((p) -> System.out.printf("%s %s; ", p.getFirstName(), p.getLastName()));
phpProgrammers.forEach((p) -> System.out.printf("%s %s; ", p.getFirstName(), p.getLastName()));
私たちはforEachメソッドを使用して、プログラマーの給料を5%増やします.
System.out.println(" 5% :");
Consumer<Person> giveRaise = e -> e.setSalary(e.getSalary() / 100 * 5 + e.getSalary());
javaProgrammers.forEach(giveRaise);
phpProgrammers.forEach(giveRaise);
もう1つの有用な方法はフィルタフィルタ()で、月給が1400ドルを超えるPHPプログラマーを表示します.
System.out.println(" $1,400 PHP :")
phpProgrammers.stream()
.filter((p) -> (p.getSalary() > 1400))
.forEach((p) -> System.out.printf("%s %s; ", p.getFirstName(), p.getLastName()));
フィルタを定義し、再利用して他の操作を実行することもできます.
// filters
Predicate<Person> ageFilter = (p) -> (p.getAge() > 25);
Predicate<Person> salaryFilter = (p) -> (p.getSalary() > 1400);
Predicate<Person> genderFilter = (p) -> ("female".equals(p.getGender()));
System.out.println(" 24 $1,400 PHP :");
phpProgrammers.stream()
.filter(ageFilter)
.filter(salaryFilter)
.filter(genderFilter)
.forEach((p) -> System.out.printf("%s %s; ", p.getFirstName(), p.getLastName()));
// filters
System.out.println(" 24 Java programmers:");
javaProgrammers.stream()
.filter(ageFilter)
.filter(genderFilter)
.forEach((p) -> System.out.printf("%s %s; ", p.getFirstName(), p.getLastName()));
limitメソッドを使用すると、結果セットの数を制限できます.
System.out.println(" 3 Java programmers:");
javaProgrammers.stream()
.limit(3)
.forEach((p) -> System.out.printf("%s %s; ", p.getFirstName(), p.getLastName()));
System.out.println(" 3 Java programmers:");
javaProgrammers.stream()
.filter(genderFilter)
.limit(3)
.forEach((p) -> System.out.printf("%s %s; ", p.getFirstName(), p.getLastName()));
ソートは?streamで処理できますか?答えは肯定的だ.次の例では、Javaプログラマーを名前と給与に基づいてソートし、リストに配置してリストを表示します.
System.out.println(" name , 5 Java programmers:");
List<Person> sortedJavaProgrammers = javaProgrammers
.stream()
.sorted((p, p2) -> (p.getFirstName().compareTo(p2.getFirstName())))
.limit(5)
.collect(toList());
sortedJavaProgrammers.forEach((p) -> System.out.printf("%s %s; %n", p.getFirstName(), p.getLastName()));
System.out.println(" salary Java programmers:");
sortedJavaProgrammers = javaProgrammers
.stream()
.sorted( (p, p2) -> (p.getSalary() - p2.getSalary()) )
.collect( toList() );
sortedJavaProgrammers.forEach((p) -> System.out.printf("%s %s; %n", p.getFirstName(), p.getLastName()));
最低賃金と最高賃金だけに興味がある場合は、ソート後に最初の/最後の1つを選択するよりも速いのはminとmaxの方法です.
System.out.println(" Java programmer:");
Person pers = javaProgrammers
.stream()
.min((p1, p2) -> (p1.getSalary() - p2.getSalary()))
.get()
System.out.printf("Name: %s %s; Salary: $%,d.", pers.getFirstName(), pers.getLastName(), pers.getSalary())
System.out.println(" Java programmer:");
Person person = javaProgrammers
.stream()
.max((p, p2) -> (p.getSalary() - p2.getSalary()))
.get()
System.out.printf("Name: %s %s; Salary: $%,d.", person.getFirstName(), person.getLastName(), person.getSalary())
上記の例ではcollectメソッドがどのように動作しているかを示しています.mapメソッドと組み合わせて、collectメソッドを使用して、結果セットを文字列、Set、またはTreeSetに配置できます.
System.out.println(" PHP programmers first name :");
String phpDevelopers = phpProgrammers
.stream()
.map(Person::getFirstName)
.collect(joining(" ; ")); // (token)
System.out.println(" Java programmers first name Set:");
Set<String> javaDevFirstName = javaProgrammers
.stream()
.map(Person::getFirstName)
.collect(toSet());
System.out.println(" Java programmers first name TreeSet:");
TreeSet<String> javaDevLastName = javaProgrammers
.stream()
.map(Person::getLastName)
.collect(toCollection(TreeSet::new));
Streamsはパラレル(parallel)でもよい.例は次のとおりです.
System.out.println(" Java programmers money:");
int totalSalary = javaProgrammers
.parallelStream()
.mapToInt(p -> p.getSalary())
.sum();
summaryStatistics法を用いてstream中の要素の様々な要約データを得ることができる.次に、getMax、getMin、getSum、getAverageなどの方法にアクセスします.
// count, min, max, sum, and average for numbers
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
IntSummaryStatistics stats = numbers
.stream()
.mapToInt((x) -> x)
.summaryStatistics();
System.out.println("List : " + stats.getMax());
System.out.println("List : " + stats.getMin());
System.out.println(" : " + stats.getSum());
System.out.println(" : " + stats.getAverage());
3.まとめ
これらの操作はFlinkのチェーン操作と似ているかどうか.
リファレンス