java基礎——Lambda表達式

什麼是Lambda

  • Lambda表達式也被稱爲箭頭函數、匿名函數、閉包。
  • Lambda表達式體現的是輕量級函數式編程思想。
  • ‘->’ 符號式Lambda表達式核心操作符號,符號左側是操作參數,符號右側是操作表達式。
  • JDK8 新特性。

我們來看一個Lambda的例子:

        //1 匿名內部類
        new Thread(new Runnable() {

            public void run() {
                System.out.println("threading....");
            }
        }).start();

        //2 Lambda模式
        new Thread(() -> {
            System.out.println("Lambda threading....");
        }).start();

Lambda表達式是對現有解決方案的語義化優化。需要根據實際需求考慮性能問題。

函數式接口

函數式接口(Functional Interface)就是一個有且僅有一個抽象方法,但是可以有多個非抽象方法的接口。@FunctionalInterface用來檢測是否符合函數式接口。例如:

/**
 * @program zookeeper
 * @description: 用戶身份認證標記接口
 * @author: xyhua
 * @create: 2019/11/26 22:31
 */
@FunctionalInterface
public interface IUserCredential {
    /**
     * 通過用戶賬號,驗證用戶身份信息的接口
     * @param username
     * @return
     */
    String verifyUser(String username);

	    /**
     * 默認方法 所有子類都可以調用
     * @param username
     * @return
     */
    default String getCredential(String username) {
        if("admin".equals(username)) {
            return "admin " + "系統管理員";
        } else if("manage".equals(username)) {
            return "manage " + "用戶管理員用戶";
        } else {
            return "commons " + "普通會員用戶";
        }
    }

    /**
     * 靜態方法 可以通過類調用
     * @param username
     * @return
     */
    static String validateUserName(String username) {
        if(Objects.nonNull(username)) {
            return username;
        } else {
            return "";
        }
    }

    /**
     * 從Object繼承的方法 不會影響函數式接口
     * @return
     */
    String toString();	
}

java中的Lambda表達式,核心就是一個函數式接口的實現。例如:

        //1 匿名內部類
        IUserCredential iu = new IUserCredential() {
            @Override
            public String verifyUser(String username) {
                return "admin".equals(username)? "管理員":"會員";
            }
        };

        //2 Lambda
        IUserCredential iu1 = (String username) -> {
            return "admin".equals(username)? "管理員":"會員";
        };

java.util.function 函數式接口

  • java.util.function.Predicate

    接收參數對象T,返回一個boolean類型結果。

            Predicate<String> predicate = (String username) -> {
                return "admin".equals(username);
            };
            System.out.println(predicate.test("admin"));
            System.out.println(predicate.test("manager"));
    
  • java.util.function.Consumer

    接收參數對象T,不返回結果。

            Consumer<String> consumer = (String message) -> {
                System.out.println("發送重要消息:" + message);
                System.out.println("發送消息結束");
            };
            consumer.accept("喫飯了");
    
  • java.util.function.Function<T,R>

    接收參數對象T,返回結果對象R。

             Function<String, Integer> function = (String gender) -> {
                return "male".equals(gender)?1:0;
            };
            System.out.println(function.apply("male"));
            System.out.println(function.apply("female"));
    
  • java.util.function.Supplier

    不接受參數,提供T對象對創建工廠。

        Supplier<String> supplier = () -> {
            return UUID.randomUUID().toString();
        };
        System.out.println(supplier.get());
        System.out.println(supplier.get());
    
  • java.util.function.UnaryOperator

    接收參數對象T,返回結果對象T

            UnaryOperator<String> unaryOperator = (String img) -> {
                img += "[100*200]";
                return img;
            };
            System.out.println(unaryOperator.apply("原圖"));
    
  • java.util.function.Binaryoperator

    接受兩個T對象,返回一個T對象結果。

            BinaryOperator<Integer> binaryOperator = (Integer i1, Integer i2) -> {
                return i1>i2?i1:i2;
            };
            System.out.println(binaryOperator.apply(1,2));
    

Lambda表達式基本知識

Lambda表達式基本語法
  1. lambda表達式,必須和接口進行綁定。
  2. lambda表達式的參數,可以附帶0個到1個參數,括號中的參數類型可以不用指定,jvm在運行時,會自動根據綁定的抽象方法中的參數類型進行推導。
  3. lambda表達式的返回值,如果代碼塊只有一行,並且沒有大括號,不用寫return關鍵字,單行代碼的執行結果會自動返回,如果添加了大括號,或者有多行代碼,必須通過return關鍵字返回執行結果。
Lambda原理
  1. Lambda表達式在JVM底層解析成私有靜態方法和匿名內部類型。
  2. 通過實現接口的匿名內部類型中接口方法調用靜態實現方法,完成Lambda表達式的執行。

stream操作

批量數據 轉化成 stream對象
        //多個數據
        Stream stream = Stream.of("admin", "tom", "damu");

        //數組
        String[] strArrays = new String[]{"xueqi", "lijie"};
        Stream<String> stream1 = Arrays.stream(strArrays);

        //列表
        List<String> list = new ArrayList<>();
        list.add("糖豆");
        list.add("雪糕");
        Stream<String> stream2 = list.stream();

        //集合
        Set<String> set = new HashSet<>();
        set.add("糖豆");
        set.add("雪糕");
        Stream<String> stream3 = set.stream();

        //Map
        Map<String, Integer> map = new HashMap<>();
        map.put("tom", 1000);
        map.put("jerry", 2000);
        Stream stream4 = map.entrySet().stream();
stream對象對於基本數據類型的功能封裝
        IntStream.of(new int[]{10, 20, 30}).forEach(System.out::println);
        IntStream.range(11, 15).forEach(System.out::println);
        IntStream.rangeClosed(1, 5).forEach(System.out::println);
stream對象 轉化成 指定的數據類型
        Stream stream = Stream.of("admin", "tom", "damu");
        // 數組
        Object[] objx = stream.toArray(String[]::new);
        // 字符串
        String str = stream.collect(Collectors.joining()).toString();
        // 列表
        List<String> collect = (List<String>) stream.collect(Collectors.toList());
        // 集合
        Set<Set> sets = (Set<Set>) stream.collect(Collectors.toSet());
        // Map
        Map<String, String> mapx = (Map<String, String>) stream.collect(Collectors.toMap(x ->x, y -> "value" + y));
stream集合操作
        List<String> accountList = new ArrayList<>();
        accountList.add("songjiang");
        accountList.add("lujunyi");
        accountList.add("wuyong");
        accountList.add("linchong");
        accountList.add("likui");
        accountList.add("wusong");

        // map() 中間操作,map()方法
        accountList = accountList.stream().map(x -> "梁山好漢:" + x).collect(Collectors.toList());
        accountList.forEach(System.out::println);

        // filter() 添加過濾條件,過濾符合條件的用戶
        accountList = accountList.stream().filter(x -> x.length() > 5).collect(Collectors.toList());
        accountList.forEach(System.out::println);

        // peek() 中間操作,迭代數據完成數據的依次處理過程
        accountList.stream()
                .peek(x -> System.out.println("peek 1:" + x))
                .peek(x -> System.out.println("peek 2:" + x))
                .forEach(System.out::println);

        // stream中對於數字運算的支持
        List<Integer> intList = new ArrayList<>();
        intList.add(20);
        intList.add(19);
        intList.add(7);
        intList.add(87);
        intList.add(2);

        // skip() 中間操作,有狀態,跳過部分數據
        intList.stream().skip(3).forEach(System.out::println);

        // limit() 中間操作,有狀態,限制輸出數據量
        intList.stream().skip(3).limit(2).forEach(System.out::println);

        // distinct() 中間操作,有狀態,剔除重複的數據
        intList.stream().distinct().forEach(System.out::println);

        // sorted() 中間操作,有狀態,排序
        // max() 獲取最大值
        // min() 獲取最小值
        // reduce() 合併處理數據
        Optional<Integer> reduce = intList.stream().reduce((sum, x) -> sum + x);
        System.out.println(reduce.get());
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章