JAva 8のlamdba式のいくつかの使い方?


1. Runnableスレッドの実装例
()->を使用して匿名クラスを置き換えます.
//Before Java 8:
new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("Before Java8 ");
    }
}).start();

//Java 8 way:
new Thread( () -> System.out.println("In Java8!") ).start();
     
Output:
too much code, for too little to do
Lambda expression rocks !!

次の構文を使用してLambdaを実装できます.
(params) -> expression (params) -> statement (params) -> { statements }
メソッドが出力などのメソッドパラメータを変更しない場合は、以下のように簡単に書くことができます.
() -> System.out.println("Hello Lambda Expressions");
メソッドが2つのメソッドパラメータを受け入れる場合は、次のようにします.
(int even, int odd) -> even + odd  
2.イベント処理の実装
Swingプログラミングをしたことがある場合は、イベントリスナーコードを書くことを忘れません.Lambda式を使用して、より良いイベントリスナーのコードを以下に示します.
// Before Java 8:
JButton show =  new JButton("Show");
show.addActionListener(new ActionListener() {
     @Override
     public void actionPerformed(ActionEvent e) {
           System.out.println("without lambda expression is boring");
        }
     });


// Java 8 way:
show.addActionListener((e) -> {
    System.out.println("Action !! Lambda expressions Rocks");
});

Java 8では、醜い匿名クラスの代わりにLambda式を使用できます.
 
3.Lambda式を使用してListセットを巡回する
//Prior Java 8 :
List features = Arrays.asList("Lambdas", "Default Method", 
"Stream API", "Date and Time API");
for (String feature : features) {
   System.out.println(feature);
}

//In Java 8:
List features = Arrays.asList("Lambdas", "Default Method", "Stream API",
 "Date and Time API");
features.forEach(n -> System.out.println(n));

// Even better use Method reference feature of Java 8
// method reference is denoted by :: (double colon) operator
// looks similar to score resolution operator of C++
features.forEach(System.out::println);

Output:
Lambdas
Default Method
Stream API
Date and Time API

メソッドリファレンスは、2つのコロンを使用します.この操作記号です.
4.Lambda式と関数インタフェースの使用
関数のプログラミングをサポートするために、Java 8は新しいパッケージjavaを追加した.util.function、インタフェースjavaが1つあります.util.function.PredicateはLambda関数のプログラミングをサポートしています.
public static void main(args[]){
  List languages = Arrays.asList("Java", "Scala", "C++", "Haskell", "Lisp");

  System.out.println("Languages which starts with J :");
  filter(languages, (str)->str.startsWith("J"));

  System.out.println("Languages which ends with a ");
  filter(languages, (str)->str.endsWith("a"));

  System.out.println("Print all languages :");
  filter(languages, (str)->true);

   System.out.println("Print no language : ");
   filter(languages, (str)->false);

   System.out.println("Print language whose length greater than 4:");
   filter(languages, (str)->str.length() > 4);
}

 public static void filter(List names, Predicate condition) {
    for(String name: names)  {
       if(condition.test(name)) {
          System.out.println(name + " ");
       }
    }
  }
}

Output:
Languages which starts with J :
Java
Languages which ends with a
Java
Scala
Print all languages :
Java
Scala
C++
Haskell
Lisp
Print no language :
Print language whose length greater than 4:
Scala
Haskell

//Even better
 public static void filter(List names, Predicate condition) {
    names.stream().filter((name) -> (condition.test(name)))
        .forEach((name) -> {System.out.println(name + " ");
    });
 }

Stream APIからのfilterメソッドはPredicateパラメータを受け入れることができ、複数の条件をテストすることができます.
 
5.複雑な組み合わせPredicate使用
java.util.function.Predicateは、and()、or()およびxor()を提供し、たとえば、文字列の「J」で始まる4つの長さを得るために論理的に操作できます.
// We can even combine Predicate using and(), or() And xor() logical functions
 // for example to find names, which starts with J and four letters long, you
 // can pass combination of two Predicate
 Predicate startsWithJ = (n) -> n.startsWith("J");
 Predicate fourLetterLong = (n) -> n.length() == 4;
   
 names.stream()
      .filter(startsWithJ.and(fourLetterLong))
      .forEach((n) -> System.out.print("
Name, which starts with 'J' and four letter long is : " + n));

ここでstartsWithJ.and(fourLetterLong)はAND論理操作を用いた.
 
6.LambdaによるMapとReduceの実装
最もポピュラーな関数プログラミングの概念はmapで、それはあなたのオブジェクトを変えることができます.この例では、costBeforeTeaxセットの各要素を一定の数値を増加させ、Lambda式x->x*xをmap()メソッドに転送し、streamにある要素に適用します.次にforEach()を使用してこのセットの要素を印刷します.
// applying 12% VAT on each purchase
// Without lambda expressions:
List costBeforeTax = Arrays.asList(100, 200, 300, 400, 500);
for (Integer cost : costBeforeTax) {
      double price = cost + .12*cost;
      System.out.println(price);
}

// With Lambda expression:
List costBeforeTax = Arrays.asList(100, 200, 300, 400, 500);
costBeforeTax.stream().map((cost) -> cost + .12*cost)
                      .forEach(System.out::println);

Output
112.0
224.0
336.0
448.0
560.0
112.0
224.0
336.0
448.0
560.0

reduce()は、SQL文のsum()、avg()またはcount()のようなコレクション内のすべての値を1つに結合します.
// Applying 12% VAT on each purchase
// Old way:
List costBeforeTax = Arrays.asList(100, 200, 300, 400, 500);
double total = 0;
for (Integer cost : costBeforeTax) {
 double price = cost + .12*cost;
 total = total + price;
 
}
System.out.println("Total : " + total);

// New way:
List costBeforeTax = Arrays.asList(100, 200, 300, 400, 500);
double bill = costBeforeTax.stream().map((cost) -> cost + .12*cost)
                                    .reduce((sum, cost) -> sum + cost)
                                    .get();
System.out.println("Total : " + bill);

Output
Total : 1680.0
Total : 1680.0

 
7.filteringで文字列Stringのセットを作成する
Filteringは大規模なCollection操作の一般的な操作であり、Streamはfilter()メソッドを提供し、Predicateオブジェクトを受け入れ、lambda式をフィルタロジックとしてこのメソッドに入力できることを意味します.
// Create a List with String more than 2 characters
List filtered = strList.stream().filter(x -> x.length()> 2)
                                        .collect(Collectors.toList());
System.out.printf("Original List : %s, filtered list : %s %n", 
                  strList, filtered);

Output :
Original List : [abc, , bcd, , defg, jk], filtered list : [abc, bcd, defg]

 
8.集合内の各要素に関数を適用する
表中の各要素に1つの値を乗じたり除算したりするなど、集合中の要素に一定の機能を用いることがしばしば必要である.
// Convert String to Uppercase and join them using coma
List G7 = Arrays.asList("USA", "Japan", "France", "Germany", 
                                "Italy", "U.K.","Canada");
String G7Countries = G7.stream().map(x -> x.toUpperCase())
                                .collect(Collectors.joining(", "));
System.out.println(G7Countries);

Output : 
USA, JAPAN, FRANCE, GERMANY, ITALY, U.K., CANADA

文字列を大文字に変換し、カンマで並べます.
 
9.異なる値をコピーしてサブリストを作成する
Streamのdistinct()メソッドを使用して、集合内の重複要素をフィルタします.
// Create List of square of all distinct numbers
List numbers = Arrays.asList(9, 10, 3, 4, 7, 3, 4);
List distinct = numbers.stream().map( i -> i*i).distinct()
                                         .collect(Collectors.toList());
System.out.printf("Original List : %s,  Square Without duplicates :
                   %s %n", numbers, distinct);

Output :
Original List : [9, 10, 3, 4, 7, 3, 4],  Square Without 
                                         duplicates : [81, 100, 9, 16, 49]

 
10.リスト内の要素の最大値、最小値、総和および平均値を計算する
//Get count, min, max, sum, and average for numbers
List primes = Arrays.asList(2, 3, 5, 7, 11, 13, 17, 19, 23, 29);
IntSummaryStatistics stats = primes.stream().mapToInt((x) -> x)
                                            .summaryStatistics();
System.out.println("Highest prime number in List : " + stats.getMax());
System.out.println("Lowest prime number in List : " + stats.getMin());
System.out.println("Sum of all prime numbers : " + stats.getSum());
System.out.println("Average of all prime numbers : " + stats.getAverage());

Output : 
Highest prime number in List : 29
Lowest prime number in List : 2
Sum of all prime numbers : 129
Average of all prime numbers : 12.9