標籤:ons 抽象 string類 parameter 理解 str 應用 隨機 箭頭
Lambda
1.Lambda運算式概念
Lambda運算式是一個匿名函數,可理解為是一段可以傳遞的代碼(即將函數像資料一樣傳遞)。
Lambda運算式需要函數式介面(即只有一個抽象方法的介面)的支援。
Lambda操作符:->,該箭頭一樣的操作符將Lambda運算式拆分成兩側,
其中左側寫Lambda運算式的參數列表(介面中抽象方法的參數);右側寫Lambda運算式所需執行的功能(抽象方法的實現),即Lambda體。
2.Lambda運算式的基本文法
文法:
(parameters) -> expression
或
(parameters) ->{ statements; }
3.基礎寫法
我們先看幾個簡單的Lambda運算式的例子:
// 1. 不需要參數,傳回值為 5 () -> 5 // 2. 接收一個參數(數字類型),返回其2倍的值 x -> 2 * x // 3. 接受2個參數(數字),並返回他們的差值 (x, y) ->x –y // 4. 接收2個Integer型整數,返回他們的和 (Integer x, Integer y) ->x + y // 5. 接受一個 string 對象,並在控制台列印,不返回任何值(看起來像是返回void) (String s) ->System.out.print(s) |
通過上述幾個簡單例子我們總結一下Lambda運算式的基本寫法:
1).左側類型可以不寫;
2).左側只有一個參數時小括弧也可省略;
3)右側只有一條語句時,大括弧和return都可省略;
4)右側有多條語句,必須要有大括弧。
4.Lambda運算式用在for迴圈中
String[] names={"Mike","Mary","Eric","Lucy","Rose"}; List<String> students=Arrays.asList(names); // 以前的迴圈方式 for (String student: students) { System.out.print(student+ "; "); } //方式一: 使用 lambda 運算式以及函數操作 students.forEach((student) -> System.out.print(student+ "; ")); //方式二:使用雙冒號操作符(Lambda運算式方法引用的第一種文法格式,下面會講 ) students.forEach(System.out::println); |
5.Lambda運算式的方法引用(雙冒號操作符)
當Lambda體中的內容已有方法實現,此時可以使用方法引用,有三種文法格式:
1)對象::執行個體方法名
例:Consumer<String> con=(x)->System.out.println(x);可以寫為:
Consumer<String> con=System.out::println;//System.out即PrintWriter對象
2)類::靜態方法名
例:Comparator<Integer> com=(x,y)->Integer.compare(x,y);可以寫為:
Comparator<Integer> com=Integer::compare;
3)類::執行個體方法名
例:BiPredicate<String,String> bp=(x,y)->x.equals(y);
BiPredicate<String,String> bp=String::equals;
注意:只有當Lambda參數列表中的第一個參數是執行個體方法的調用者,而第二個參數是執行個體方法的參數時,可以使用第3)種文法格式類::執行個體方法名。如上述例子中第一個參數x是執行個體方法x.equals(y)的調用者,第二個參數y是方法的參數。
資料流Stream
1.流的擷取
1)通過集合Collection擷取
List<Integer> list = new ArrayList<Integer>(Arrays.asList(1,2,3,4,5)); Stream<Integer> stream = list.stream(); |
2)通過數組擷取
String[] array = {"are","you","ok"}; Stream<String> stream = Array.stream(array); //對於基本類型數組的處理 int[] array = {1,2,3,4,5}; //此時Arrays.stream(array)擷取的是一個IntStream對象 Stream<Integer> stream = Arrays.stream(array).boxed(); |
3)通過值擷取(此方式存在缺陷)
Stream<String> stream = Stream.of("are","you","ok"); |
2.篩選filter
filter函數接收一個Lambda運算式作為參數,該運算式返回boolean,在執行過程中,流將元素逐一輸送給filter,並篩選出執行結果為true的元素;
//篩選出列表中的非空項 List<String> list = Arrays.asList("are","you","","ok"); List<String> filted = list.stream() .filter(x-> !x.empty()) .collect(Collectors.toList()); |
3.去重、截取、跳過
去重distinct:
List<String> list = Arrays.asList("are","you","you","ok"); List<String> distincted = list.stream() .distinct() .collect(Collectors.toList()); |
截取流的前n個元素: .limit(3)
跳過流的前n個元素: .skip(2)
4.映射 map
對流中的每個元素執行一個函數,使得元素轉換成另一種類型輸出。流會將每一個元素輸送給map函數,並執行map中的Lambda運算式,最後將執行結果存入一個新的流中。
如:將 list 中每一個 Integer類型元素自增後轉化為 String類型
List<Integer> list = Arrays.asList(1,2,3,4,5); List<String> result = list.stream() .map(x->String.valueOf(++x)) .collect(Collectors.toList()); |
5.合并多個流 flatMap
List<String> list1 = ..... List<String> list2 = ... List<List<String>> list = Arrays.asList(list1,list2); //將list中的list1,list2合并為一個List<String> List<String> listsum = list.stream() .flatMap(List::stream) .collect(Collectors.toList()); 以下一個實際的應用例子:列出 list 中各不相同的單詞 List<String> list = new ArrayList<String>(); list.add("I am a boy"); list.add("I love the girl"); list.add("But the girl loves another girl"); list.stream().map(line->line.split(" ")) //將每一個項分詞,並映射為數組 //將每一個分項數組組合并到主流中,形成一個包含所有分項數組的總數組流 .flatMap(Arrays::stream) .distinct(); //去重 .forEach(System.out::println); //列印 |
6.匹配元素
1) 是否匹配任一元素:anyMatch
2) 是否匹配所有元素:allMatch
3) 是否未匹配所有元素:noneMatch
7.擷取元素
1) 擷取任一元素 :findAny
2) 擷取第一個元素:findFirst
Optional 對象介紹
Optional是Java8新加入的一個容器,這個容器只存1個或0個元素,它用於防止出現NullpointException,它提供如下方法:
- isPresent() 判斷容器中是否有值。
- ifPresent(Consume lambda) 容器若不為空白則執行括弧中的Lambda運算式。
- T get() 擷取容器中的元素,若容器為空白則拋出NoSuchElement異常。
- T orElse(T other) 擷取容器中的元素,若容器為空白則返回括弧中的預設值。
8.遍曆流 forEach
forEach方法遍曆流中每個元素,參數為一個Lambda運算式,用於對每一個遍曆的元素執行的操作;
//輸出10個隨機數 Random random = new Random(); random.ints().limit(10).forEach(System.out::println); |
Lambda、stream