CentOS安裝mysql、MariaDB
阿新 • • 發佈:2022-05-16
一、Lambda表示式
-
Lambda 是一個匿名函式,我們可以把Lambda 表示式理解為是一段可以傳遞的程式碼(將程式碼像資料一樣進行傳遞)。使用它可以寫出更簡潔、更靈活的程式碼。作為一種更緊湊的程式碼風格,使Java的語言表達能力得到了提升。
- 格式:
- lambda操作符或箭頭操作符
- 左邊:lambda形參列表(其實就是藉口中的抽象方法的形參列表)
- 右邊:lambda體(其實就是重寫的抽象方法的方法體)
- lambda表示式的本質:作為介面的例項
lambda表示式舉例:
- 語法格式一:無參,無返回值
1 public class Test02 { 2 int num = 10; //jdk 1.7以前 必須final修飾 3 4 @Test 5 public void test01(){ 6 //匿名內部類 7 new Runnable() { 8 @Override 9 public void run() { 10 //在區域性類中引用同級區域性變數 11 //只讀 12 System.out.println("Hello World" + num);13 } 14 }; 15 } 16 17 @Test 18 public void test02(){ 19 //lambda表示式 20 Runnable runnable = () -> { 21 System.out.println("Hello Lambda,我是run()函式"); 22 }; 23 } 24 }
- 語法格式二 :有一個引數,沒有返回值
- 語法格式三:若只有一個引數,小括號可以省略不寫 a -> System.out.println(a)
- 語法格式四:資料型別可以省略不寫,由JVM編譯器通過上下文推斷得出
1 @Test 2 public void test03(){ 3 Consumer<String> consumer = (a) -> System.out.println(a); 4 consumer.accept("我省略了accept函式名!"); 5 }
- 語法格式五:Lambda需要兩個或以上的引數,多條執行語句,並且可以有返回值
1 @Test 2 public void test04(){ 3 Comparator<Integer> comparator = (a, b) -> { 4 System.out.println("比較介面"); 5 return Integer.compare(a, b); 6 }; 7 }
- 語法格式六:當若 Lambda 體中只有一條語句, return 和 大括號都可以省略不寫
1 Comparator<Integer> com = (x, y) -> Integer.compare(x, y);
二、函式式介面
- 如果一個介面中,只聲明瞭一個抽象方法,則此介面就稱為函式式介面
java內建四大核心函式式介面
- 消費型介面
1 /** 2 * Consumer<T> 消費型介面 : 3 */ 4 @Test 5 public void consumerTest() { 6 happy(2999.99, m -> System.out.println("此次消費了:" + m + "元")); 7 } 8 9 public void happy(Double money, Consumer<Double> consumer) { 10 consumer.accept(money); 11 }
- 提供型介面
1 /** 2 * Supplier<T> 供給型介面 : 3 */ 4 @Test 5 public void supplierTest() { 6 Random random = new Random(); 7 List<Integer> numList = getNumList(10, () -> random.nextInt(100)); 8 numList.forEach(System.out::println); 9 } 10 11 /** 12 * 需求:產生指定個數的整數,並放入集合中 13 * 14 * @param num 15 * @param sup 16 * @return 17 */ 18 public List<Integer> getNumList(int num, Supplier<Integer> sup) { 19 List<Integer> list = new ArrayList<>(); 20 21 for (int i = 0; i < num; i++) { 22 Integer n = sup.get(); 23 list.add(n); 24 } 25 26 return list; 27 }
- 函式型介面
1 /** 2 * Function<T, R> 函式型介面 3 */ 4 @Test 5 public void functionTest() { 6 // s -> s.trim() 可替換成 String::trim 7 String newStr = strHandler("\t\t\t 威武 ", s -> s.trim()); 8 System.out.println(newStr); 9 10 String subStr = strHandler(" 威武呀", s -> s.substring(2, 5)); 11 System.out.println(subStr); 12 } 13 14 /** 15 * 需求:用於處理字串 16 * 17 * @param str 18 * @param fun 19 * @return 20 */ 21 public String strHandler(String str, Function<String, String> fun) { 22 return fun.apply(str); 23 }
- 斷言型介面
1 /** 2 * Predicate<T> 斷言型介面: 3 */ 4 @Test 5 public void predicateTest(){ 6 List<String> list = Arrays.asList("Hello", "yxj", "Lambda", "www", "ok"); 7 List<String> strings = filterStr(list, p -> p.length() > 3); 8 strings.forEach(System.out::println); 9 } 10 11 /** 12 * 需求:將滿足條件的字串,放入集合中 13 * 14 * @param list 15 * @param pre 16 * @return 17 */ 18 public List<String> filterStr(List<String> list, Predicate<String> pre) { 19 List<String> strList = new ArrayList<>(); 20 21 for (String str : list) { 22 if (pre.test(str)) { 23 strList.add(str); 24 } 25 } 26 27 return strList; 28 }
三、方法引用和構造器引用
(1)
1.方法引用:若 Lambda 體中的功能,已經有方法提供了實現,可以使用方法引用(可以將方法引用理解為 Lambda 表示式的另外一種表現形式)
2.方法引用本質上就是lambda表示式
3.使用格式: 類(或物件) ::方法名
4.具體分為如下三種情況:
物件 ::非靜態方法
類::靜態方法
類::非靜態方法
①:
1 /** 2 * 物件::例項方法 3 */ 4 @Test 5 public void test01() { 6 PrintStream printStream = System.out; 7 Consumer<String> consumer = s -> printStream.println(s); 8 consumer.accept("aaa"); 9 10 Consumer<String> consumer2 = printStream::println; 11 consumer2.accept("bbb"); 12 } 13 14 @Test 15 public void test02(){ 16 Employee emp = new Employee(101, "張三", 18, 9999.99); 17 Supplier<String> supplier = ()->emp.getName(); 18 System.out.println(supplier.get()); 19 20 Supplier<String> supplier2 = emp::getName; 21 System.out.println(supplier2.get()); 22 } 23 24 @Test 25 public void test03(){ 26 BiFunction<Double, Double, Double> fun = (x, y) -> Math.max(x, y); 27 Double apply = fun.apply(99.99, 199.99); 28 System.out.println(apply); 29 30 BiFunction<Double, Double, Double> fun2 = Math::max; 31 Double apply1 = fun2.apply(88.88, 188.88); 32 System.out.println(apply1); 33 }
②
1 /** 2 * 類名 :: 靜態方法名 3 */ 4 @Test 5 public void test02() { 6 Comparator<Integer> comparator = (a, b) -> Integer.compare(a, b); 7 System.out.println(comparator.compare(1, 2)); 8 9 Comparator<Integer> comparator2 = Integer::compare; 10 System.out.println(comparator2.compare(10, 20)); 11 }
③
1 /** 2 * 類名 :: 例項方法名 3 */ 4 @Test 5 public void test05() { 6 BiPredicate<String, String> bp = (x, y) -> x.equals(y); 7 boolean test = bp.test("hello word", "hello future"); 8 9 BiPredicate<String, String> bp2 = String::equals; 10 boolean test2 = bp2.test("hello word", "hello future"); 11 12 System.out.println("-----------------------------------------"); 13 14 Function<Employee, String> function = e -> e.show(); 15 String apply = function.apply(new Employee()); 16 System.out.println(apply); 17 18 Function<Employee, String> function2 = Employee::show; 19 String apply1 = function2.apply(new Employee()); 20 System.out.println(apply1); 21 }
(2)構造器引用
1 /** 2 * 構造器引用 3 */ 4 @Test 5 public void test06() { 6 Supplier<Employee> supplier = () -> new Employee(); 7 Employee employee = supplier.get(); 8 System.out.println(employee); 9 10 Supplier<Employee> supplier1 = Employee::new; 11 Employee employee1 = supplier1.get(); 12 System.out.println(employee1); 13 } 14 15 @Test 16 public void test07(){ 17 Supplier<List> supplier = ()->new ArrayList<Integer>(); 18 List list = supplier.get(); 19 list.add(1); 20 list.add(2); 21 System.out.println(list); 22 23 Supplier<List> supplier1 = ArrayList::new; 24 List list1 = supplier1.get(); 25 System.out.println(list1); 26 }
(3)陣列引用
1 /** 2 * 陣列引用 3 */ 4 @Test 5 public void test08(){ 6 Function<Integer, String[]> fun = (args)->new String[args]; 7 String[] apply = fun.apply(10); 8 System.out.println("apply.length = " + apply.length); 9 10 System.out.println("--------------------------"); 11 12 Function<Integer, Employee[]> fun2 = Employee[]::new; 13 Employee[] apply1 = fun2.apply(20); 14 System.out.println("apply1.length = " + apply1.length); 15 }
四、Stream API
注意:產生一個全新的流,和原來的資料來源沒有關係(資料來源不受影響)!!!
Stream 的操作三個步驟
- 建立 Stream
- 一個數據源(如:集合、陣列),獲取一個流
- 中間操作
- 一箇中間操作鏈,對資料來源的資料進行處理
- 終止操作(終端操作)
- 一個終止操作,執行中間操作鏈,併產生結果
①Stream的建立(例項化)
1 /** 2 * 建立流 3 */ 4 @Test 5 public void test01(){ 6 /** 7 * 方式一:集合流 8 * - Collection.stream() 序列流 9 * - Collection.parallelStream() 並行流 10 */ 11 List<String> list = new ArrayList<>(); 12 Stream<String> stream1 = list.stream(); 13 14 //方式二:陣列流 15 //Arrays.stream(array) 16 String[] strings = new String[10]; 17 Stream<String> stream2 = Arrays.stream(strings); 18 19 //方式三:Stream 靜態方法 20 //Stream.of(...) 21 Stream<Integer> stream3 = Stream.of(1, 2, 3); 22 23 //方式四:無限流(瞭解) 24 //迭代 25 Stream<Integer> stream4 = Stream.iterate(0, (i) -> i+2); 26 stream4.forEach(System.out::println); 27 28 //生成 29 Stream.generate(() -> Math.random()) 30 .limit(5) 31 .forEach(System.out::println); 32 }
②Stream的中間操作
filter:篩選與切片
1 //2. 中間操作 2 List<Employee> emps = Arrays.asList( 3 new Employee(102, "李四", 59, 6666.66), 4 new Employee(101, "張三", 18, 9999.99), 5 new Employee(103, "王五", 28, 3333.33), 6 new Employee(104, "趙六", 8, 7777.77), 7 new Employee(104, "趙六", 8, 7777.77), 8 new Employee(104, "趙六", 8, 7777.77), 9 new Employee(105, "田七", 38, 5555.55) 10 ); 11 12 //內部迭代:迭代操作 Stream API 內部完成 13 @Test 14 public void test2(){ 15 //所有的中間操作不會做任何的處理 16 Stream<Employee> stream = emps.stream() 17 .filter((e) -> { 18 System.out.println("測試中間操作"); 19 // 加 return 原因:因為lambda表示式中,如果有多條語句,需要用大括號括起來,最後一句為返回語句,要加return 20 return e.getAge() <= 35; 21 }); 22 23 //只有當做終止操作時,所有的中間操作會一次性的全部執行,稱為“惰性求值” 24 stream.forEach(System.out::println); 25 } 26 27 //外部迭代 28 @Test 29 public void test3(){ 30 Iterator<Employee> it = emps.iterator(); 31 32 while(it.hasNext()){ 33 System.out.println(it.next()); 34 } 35 }
limit:截斷流
1 @Test 2 public void test4(){ 3 emps.stream() 4 .filter((e) -> { 5 System.out.println("短路!"); // && || 6 return e.getSalary() >= 5000; 7 }).limit(3) 8 .forEach(System.out::println); 9 }
skip(n):跳過元素
1 @Test 2 public void test5() { 3 emps.parallelStream() 4 .filter((e) -> e.getSalary() >= 5000) 5 .skip(2) 6 .forEach(System.out::println); 7 }
distinct:篩選
1 @Test 2 public void test6() { 3 emps.stream() 4 .distinct() 5 .forEach(System.out::println); 6 }
需要重寫hashCode()和equals()方法
對映:
排序:
(3)Stream的終止操作
查詢/匹配
歸約
收集
1 /** 2 * 把員工的名字收集到指定的集合中 3 */ 4 @Test 5 public void test08(){ 6 List<String> list = emps.stream().map(Employee::getName).collect(Collectors.toList()); 7 list.forEach(System.out::println); 8 9 System.out.println("--------------"); 10 11 Set<String> set = emps.stream().map(Employee::getName).collect(Collectors.toSet()); 12 set.forEach(System.out::println); 13 14 System.out.println("--------------"); 15 16 Map<Long, String> collect = emps.stream().collect(Collectors.toMap(Employee::getId, Employee::getName)); 17 System.out.println(collect); 18 }
五、Optional類
Optional 類 (java.util.Optional) 是一個容器類,代表一個值存在或不存在,原來用 null 表示一個值不存在,現在用 Optional 可以更好的表達這個概念;並且可以避免空指標異常
- Optional.of(T t):建立一個 Optional 例項
- Optional.empty(T t):建立一個空的 Optional 例項
- Optional.ofNullable(T t):若 t 不為 null,建立 Optional 例項,否則空例項
- isPresent():判斷是否包含某值
- orElse(T t):如果呼叫物件包含值,返回該值,否則返回 t
- orElseGet(Supplier s):如果呼叫物件包含值,返回該值,否則返回 s 獲取的值
- map(Function f):如果有值對其處理,並返回處理後的 Optional,否則返回 Optional.empty()
- flatmap(Function mapper):與 map 相似,要求返回值必須是 Optional
1 @Test 2 public void test01(){ 3 Optional<Employee> employee = Optional.of(new Employee()); 4 System.out.println(employee.get()); 5 6 System.out.println("=========="); 7 8 Optional<Object> o = Optional.of(null); 9 System.out.println(o.get()); 10 }