JAVA Lambda表達式的使用和教程詳細用法


首先說下Lambda表達式的優點和缺點:

優點:

  1:簡潔

  2:易並行計算,特別適合便利結果,循環計算數值或者賦值的時候很方便

缺點:

  1:若不用並行運算,很多時候計算方式速度沒有傳統的For循環快。

  2:不容易使用Debug模式調試

  3:再Lamdba語句中直接強制轉換不方便

  4:不可以再foreach中修改外面的值

Lambda表達式的基本語法:(parameters) -> expression 或 (parameters) -> { statements; }

 解釋:(parameters)這個參數名字可以自定義,但是一般要做到見名之意, -> 這個必須有   (parameters) -> expression 或 (parameters)

  ->{  方法體}

例子:

             List<Map<String,Object>> sevenTIME= jdbcTemplate.queryForList ( " SELECT * FROM operation_log_details );
              sevenTIME.forEach((ss)->{ //遍歷結果集 ss 類似於for循環中的循環值
                System.out.println(ss);//循環打印結果集

                //具體有關聯的邏輯代碼
               });

1.替代匿名內部類

毫無疑問,lambda表達式用得最多的場合就是替代匿名內部類,而實現Runnable接口是匿名內部類的經典例子。lambda表達式的功能相當強大,用()->就可以代替整個匿名內部類!請看代碼:

如果使用匿名內部類:

@Test
    public void oldRunable() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("The old runable now is using!");
            }
        }).start();
    }

而如果使用lambda表達式

@Test public void runable() {

      new Thread(() -> System.out.println("It's a lambda function!")).start();

}

2.使用lambda表達式對集合進行迭代 
Java的集合類是日常開發中經常用到的,甚至說沒有哪個java代碼中沒有使用到集合類。。。而對集合類最常見的操作就是進行迭代遍歷了。請看對比:

    public void iterTest() {
        List<String> languages = Arrays.asList("java","scala","python");
        //before java8
        for(String each:languages) {
            System.out.println(each);
        }//傳統的循環方式 方式1
        //after java8
        languages.forEach(x -> System.out.println(x));//結果集同上  方式2
        languages.forEach(System.out::println);//結果集同上  方式3
    } 

3.用lambda表達式實現map

@Test public void mapTest() {

    List<Double> cost = Arrays.asList(10.0, 20.0,30.0); cost.stream().map(x -> x + x*0.05).forEach(x -> System.out.println(x));

}

map函數可以說是函數式編程里最重要的一個方法了。map的作用是將一個對象變換為另外一個。在我們的例子中,就是通過map方法將cost增加了0,05倍的大小然后輸出

4.用lambda表達式實現map與reduce 
既然提到了map,又怎能不提到reduce。reduce與map一樣,也是函數式編程里最重要的幾個方法之一。。。map的作用是將一個對象變為另外一個,而reduce實現的則是將所有值合並為一個,請看:

@Test public void mapReduceTest() {

List<Double> cost = Arrays.asList(10.0, 20.0,30.0); double allCost = cost.stream().map(x -> x+x*0.05).reduce((sum,x) -> sum + x).get();      System.out.println(allCost);

}

最終的結果為:

63.0

如果我們用for循環來做這件事情:

@Test public void sumTest() {

List<Double> cost = Arrays.asList(10.0, 20.0,30.0); double sum = 0;

      for(double each:cost) {

       each += each * 0.05;

        sum += each;

      } System.out.println(sum);

}

5.filter操作 
filter也是我們經常使用的一個操作。在操作集合的時候,經常需要從原始的集合中過濾掉一部分元素。

@Test public void filterTest() {

   List<Double> cost = Arrays.asList(10.0, 20.0,30.0,40.0);

   List<Double> filteredCost = cost.stream().filter(x -> x > 25.0).collect(Collectors.toList()); filteredCost.forEach(x -> System.out.println(x));

}

最后的結果:

30.0 
40.0

函數式接口(Functional Interfaces),它表示只有一個抽象方法的接口,可以用來指向Lambda表達式。例如:

Consumer c = (s) -> System.out.println(s);

 

6.與函數式接口Predicate配合 
除了在語言層面支持函數式編程風格,Java 8也添加了一個包,叫做 java.util.function。它包含了很多類,用來支持Java的函數式編程。其中一個便是Predicate,使用 java.util.function.Predicate 函數式接口以及lambda表達式,可以向API方法添加邏輯,用更少的代碼支持更多的動態行為。Predicate接口非常適用於做過濾。

java.util.function詳解:
  • Function<T, R>:接受一個參數T,返回結果R

  • Predicate<T>:接受一個參數T,返回boolean

  • Supplier<T>:不接受任何參數,返回結果T

  • Consumer<T>:接受一個參數T,不返回結果

  • UnaryOperator<T>:繼承自Function<T, T>,接受一個參數T,返回相同類型T的結果

  • BiFunction<T, U, R>:接受兩個參數T和U,返回結果R

  • BinaryOperator<T>:繼承自BiFunction<T, T, T>,接受兩個相同類型T的參數,返回相同類型T的結果

  • Runnable:實際上是不接受任何參數,也不返回結果

  • Comparable<T>:實際上是接受兩個相同類型T的參數,返回int

  • Callable<V>:不接受任何參數,返回結果V

例子:

public static void main(String[] args) {
        List<String> languages = Arrays.asList("Java","Python","scala","Shell","R");
        System.out.println("Language starts with J: ");


        filterTest(languages,x -> x.startsWith("J"));
        System.out.println("\nLanguage ends with a: ");


        filterTest(languages,x -> x.endsWith("a"));
        System.out.println("\nAll languages: ");


        filterTest(languages,x -> true);
        System.out.println("\nNo languages: ");


        filterTest(languages,x -> false);
        System.out.println("\nLanguage length bigger three: ");


        filterTest(languages,x -> x.length() > 4);
    }

最后的輸出結果:

Language starts with J: 
Java

Language ends with a: 
Java 
scala

All languages: 
Java 
Python 
scala 
Shell 
R

No languages:

Language length bigger three: 
Python 
scala 
Shell

forEach+Lambda 表達式遍歷Map和List

============Java8之前的方式==========
            Map<String, Integer> items = new HashMap<>();
            items.put("A", 10);
            items.put("B", 20);
            items.put("C", 30);
            items.put("D", 40);
            items.put("E", 50);
            items.put("F", 60);
            for (Map.Entry<String, Integer> entry : items.entrySet()) {
                System.out.println("Item : " + entry.getKey() + " Count : " + entry.getValue());
            }
            ============forEach + Lambda表達式==========
            Map<String, Integer> items = new HashMap<>();
            items.put("A", 10);
            items.put("B", 20);
            items.put("C", 30);
            items.put("D", 40);
            items.put("E", 50);
            items.put("F", 60);
            items.forEach((k,v)->System.out.println("Item : " + k + " Count : " + v));
            items.forEach((k,v)->{
                System.out.println("Item : " + k + " Count : " + v);
                if("E".equals(k)){
                    System.out.println("Hello E");
                }
            });
            二遍歷List:
            ============Java8之前的方式==========

            List<String> items = new ArrayList<>();
            items.add("A");
            items.add("B");
            items.add("C");
            items.add("D");
            items.add("E");

            for(String item : items){
                System.out.println(item);
            }
            ============forEach + Lambda表達式==========
            List<String> items = new ArrayList<>();
            items.add("A");
            items.add("B");
            items.add("C");
            items.add("D");
            items.add("E");
            //輸出:A,B,C,D,E
            items.forEach(item->System.out.println(item));
            //輸出 : C
            items.forEach(item->{
                if("C".equals(item)){
                    System.out.println(item);
                }
            });

 特別強調:數組不可以直接再forEach中使用Lambda表達式

         PartnerType[] values = PartnerType.values();
        //提示Cannot resolve method 'forEach(<method reference>)
        values.forEach(System.out::println);//錯誤使用


想要使用必須轉換,如下

     PartnerType[] values = PartnerType.values();
     Arrays.stream(values).forEach(System.out::println);//轉成流
          Arrays.asList(values).forEach(System.out::println);//轉成list

lambda操作數組、集合

編寫線程

  1. Runnable runnable = () -> {
  2. System.out.println( "Lambda 創建線程");
  3. };
  4. Thread thread = new Thread(runnable);
  5. thread.start();

利用Lambda運算

  1. BinaryOperator<Integer> add = (x, y) -> x + y;
  2.  
  3. Integer x = add.apply( 20, 30);

 

統計數組中某元素出現的個數

String name[] = {"張三", "李四", "王五", "孫劉", "趙強", "李明", "趙強", "汪汪"};
long num = Arrays.stream(name).filter(x -> x.equals("趙強")).count();

數組去重並轉化成集合存儲

String name[] = {"張三", "李四", "王五", "孫劉", "趙強", "李明", "趙強", "汪汪"};
List<String> stringList = Arrays.stream(name).filter(x -> !x.equals("趙強")).collect(toList());

數組去重,並對元素加后綴

String name[] = {"張三", "李四", "王五", "孫劉", "趙強", "李明", "趙強", "汪汪"};
List<String> stringList2 = Arrays.stream(name).filter(x -> !x.equals("趙強")).map(y -> y + "加后綴:").collect(toList());

數組求和

 int[] a = {1, 2, 3, 4, 5, 6, 7, 8, 3, 4, 5, 6, 7, 8, 9, 10 };
        int count = 0;
        // for循環
        for (int i = 0; i < a.length; i++) {
            count += a[i];
        }
        // foreach
        count = 0;
        for (int i = 0; i < a.length; i++) {
            count += a[i];
        }
        // Lambda
        int num = Arrays.stream(a).reduce(0, (b, c) -> b + c);

Lambda  的提取對象字段,並拼接

class User{
 
    private String username;
    private int age;
 
    public User(){}
 
    public User(String username, int age) {
        this.username = username;
        this.age = age;
    }
 
    public String getUsername() {
        return username;
    }
 
    public void setUsername(String username) {
        this.username = username;
    }
 
    public int getAge() {
        return age;
    }
 
    public void setAge(int age) {
        this.age = age;
    }
}
 
List<User> userList = asList(new User("張三" , 10) , new User("李四" , 10) , new User("王五" , 13));
String result = userList.stream().map(User::getUsername).collect(Collectors.joining("," , "[" , "]"));
輸出結果:[張三,李四,王五]

Lambda  groupBy

        List<User> userList = asList(new User("張三" , 10) , new User("李四" , 10) , new User("王五" , 13));
        Stream<User> userStream = userList.stream();
        Map<Integer , List<String>> integerStringMap = userStream.collect(groupingBy(user->user.getAge() , mapping(User::getUsername , toList())));
        System.out.println(integerStringMap.toString());
輸出結果:{10=[張三, 李四], 13=[王五]}

 

String result2 =
                userList.stream().map(User::getUsername)
                        .reduce(new StringJoiner(",1 ", "[", "]"),
                                StringJoiner::add,
                                StringJoiner::merge)
                        .toString();
System.out.println(result2);
輸出結果:[張三,1 李四,1 王五]

 

stream()流操作
             //2.1. 去重 distinct() 去重;collect(Collectors.toList())。封裝成集合
               List<Person> distinctList = list.stream().distinct().collect(Collectors.toList());


              //2.2 排序  sorted((第一個對象,第二個對象)->返回值)  (升降序看是第幾個對象與第幾個對象比較)
              List<Person> sortedList = list.stream().sorted((o1,o2)->o1.getAge()-o2.getAge()).collect(Collectors.toList());


             //2.3 過濾 , filter(item->{})   item為每一項。 按照自己的需求來篩選list中的數據
             List<Person> filterList = list.stream().filter(item->item.getAge()>3).collect(Collectors.toList());


             //2.4 map(), 提取對象中的某一元素.  用每一項來獲得屬性(也可以直接用  對象::get屬性())
             List<String> mapList1 = list.stream().map(Person::getName).collect(Collectors.toList());
             List<String> mapList2 = list.stream().map(item->item.getName()).collect(Collectors.toList());


             //2.5 統計 sum() 。mapToDouble() 轉換成double。還有其他類型轉換。可以自己研究。
             //           max(),min(),average()
             double sum = list.stream().mapToDouble(Person::getAge).sum();


             //2.6 分組   Collectors.groupingBy(屬性名)
               Map<Integer, List<Person>> map = list.stream().collect(Collectors.groupingBy(Person::getAge));


             //2.7 多重分組 Collectors.groupingBy(屬性,Collectors.groupingBy(屬性))
             Map<String, Map<Integer, List<Person>>> map2 = list.stream().collect(Collectors.groupingBy(t->t.getName(),Collectors.groupingBy(t->t.getAge())));


             //2.8 分組並計算綜合        Collectors.summarizingLong()
             Map<String, Map<Integer, LongSummaryStatistics>> map3 = list.stream().collect(Collectors.groupingBy(t->t.getName(),Collectors.groupingBy(t->t.getAge(),Collectors.summarizingLong(Person::getSize))));
             
             /**
              *  3.  集合比較的簡寫方式
              */
             list.sort((o1,o2)->{return o1.getAge()-o2.getAge();})

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM