• Lambda8 表达式


    Lambda 表达式

    Lambda 表达式是 JDK8 的一个新特性,可以取代大部分的匿名内部类,写出更优雅的 Java 代码,尤其在集合的遍历和其他集合操作中,可以极大地优化代码结构。
    JDK 也提供了大量的内置函数式接口供我们使用,使得 Lambda 表达式的运用更加方便、高效。

    可以对某些匿名内部类的写法进行简化,它是函数式编程思想的一个重要体现,不用关注是什么对象,而是更关注对数据进行了什么操作。

    基本格式

    (参数列表)->{代码}
    

    范例

    范例一:

    在创建线程并启动时可以使用匿名内部类的写法;

    • 匿名内部类方式:
    new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println(Thread.currentThread());
        }
    }).start();
    
    • Lambda方式:
    new Thread(() -> {
        System.out.println(Thread.currentThread());
    }).start();
    

    范例二:

    IntBinaryOperator是一个接口,使用匿名内部类的写法调用该方法;

    • 匿名内部类方式:
    public static int calculateNum(IntBinaryOperator operator) {
        int a = 10;
        int b = 20;
        return operator.applyAsInt(a, b);
    }
    
    @Test
    public void testLambda2() {
        int i = calculateNum(new IntBinaryOperator() {
            @Override
            public int applyAsInt(int left, int right) {
                return left + right;
            }
        });
    
        System.out.println(i);
    }
    
    • Lambda方式:
    public static int calculateNum(IntBinaryOperator operator) {
        int a = 10;
        int b = 20;
        return operator.applyAsInt(a, b);
    }
    
    @Test
    public void testLambda2() {
        int i = calculateNum((int left, int right) -> {
            return left + right;
        });
    
        System.out.println(i);
    }
    

    范例三:

    IntPredicate是一个接口。先使用匿名内部类的写法调用该方法;

    • 匿名内部类方式:
    public static void printNum(IntPredicate predicate) {
        int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        for (int i : arr) {
            if (predicate.test(i)) {
                System.out.println(i);
            }
        }
    }
    
    @Test
    public void testLambda3() {
        printNum(new IntPredicate() {
            @Override
            public boolean test(int value) {
                return value % 3 == 0;
            }
        });
    }
    
    • Lambda方式:
    public static void printNum(IntPredicate predicate) {
        int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        for (int i : arr) {
            if (predicate.test(i)) {
                System.out.println(i);
            }
        }
    }
    
    @Test
    public void testLambda3() {
        printNum((int value) -> {
            return value % 3 == 0;
        });
    }
    

    范例四:

    Function是一个接口,先使用匿名内部类的写法调用该方法;

    • 匿名内部类方式:
    public static <R> R typeConver(Function<String, R> function) {
        String str = "1235";
        R result = function.apply(str);
        return result;
    }
    
    @Test
    public void testLambda4() {
        Integer result = typeConver(new Function<String, Integer>() {
            @Override
            public Integer apply(String s) {
                return Integer.valueOf(s);
            }
        });
        System.out.println(result);
    }
    
    • Lambda方式:
    public static <R> R typeConver(Function<String, R> function) {
        String str = "1235";
        R result = function.apply(str);
        return result;
    }
    
    @Test
    public void testLambda4() {
        Integer result = typeConver((String s) -> {
            return Integer.valueOf(s);
        });
        System.out.println(result);
    }
    

    范例五:

    IntConsumer是一个接口,先使用匿名内部类的写法调用该方法;

    • 匿名内部类方式:
    public static void foreachArr(IntConsumer consumer) {
        int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        for (int i : arr) {
            consumer.accept(i);
        }
    }
    
    @Test
    public void testLambda5() {
        foreachArr(new IntConsumer() {
            @Override
            public void accept(int value) {
                System.out.println(value);
            }
        });
    
    • Lambda方式:
    public static void foreachArr(IntConsumer consumer) {
        int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        for (int i : arr) {
            consumer.accept(i);
        }
    }
    
    @Test
    public void testLambda5() {
        foreachArr((int value) -> {
            System.out.println(value);
        });
    }
    

    省略规则

    • 参数类型可以省略;
    public static void foreachArr(IntConsumer consumer) {
        int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        for (int i : arr) {
            consumer.accept(i);
        }
    }
    
    @Test
    public void testLambda5() {
        foreachArr((value) -> {
            System.out.println(value);
        });
    }
    
    • 方法体只有一句代码时大括号return和唯一一句代码的分号可以省略;
    public static void foreachArr(IntConsumer consumer) {
        int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        for (int i : arr) {
            consumer.accept(i);
        }
    }
    
    @Test
    public void testLambda5() {
        foreachArr((value) -> System.out.println(value));
    }
    
    • 方法只有一个参数时小括号可以省略;
    public static void foreachArr(IntConsumer consumer) {
        int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        for (int i : arr) {
            consumer.accept(i);
        }
    }
    
    @Test
    public void testLambda5() {
        foreachArr(value -> System.out.println(value));
    }
    
    • 以上这些规则都记不住也可以省略不记,可通过idea的replaceLambda表达式快速生成lambda表达式;

    Stream 流

    Stream将要处理的元素集合看作一种流,在流的过程中,借助Stream API对流中的元素进行操作。

    Stream - 特性

    Stream可以由数组或集合创建,对流的操作分为两种:

    • 中间操作,每次返回一个新的流,可以有多个;
    • 终端操作,每个流只能进行一次终端操作,终端操作结束后流无法再次使用。终端操作会产生一个新的集合或值。

    Stream特性:

    • stream不存储数据,而是按照特定的规则对数据进行计算,一般会输出结果;

    • stream不会改变数据源,通常情况下会产生一个新的集合或一个值;

    • stream具有延迟执行特性,只有调用终端操作时,中间操作才会执行。

    image-20220321145135117

    Stream - 创建方式

    Stream创建方式有三种:

    • 通过 java.util.Collection.stream() 方法用集合创建流;

    • 使用java.util.Arrays.stream(T[] array)方法用数组创建流;

    • 使用Stream的静态方法:of()、iterate()、generate()。

    import java.util.Arrays;
    import java.util.List;
    import java.util.concurrent.atomic.AtomicInteger;
    import java.util.stream.Collectors;
    import java.util.stream.IntStream;
    import java.util.stream.Stream;
    
    /**
     * @author hos
     * @Createdate 2022/3/21 14:40
     */
    public class StreamCreateType {
    
        public static void main(String[] args) {
    
            /**
             * Stream 流的创建有3种方式
             *  1. Collection.stream()方法用集合创建
             *  2. Arrays.stream(T[] array) 方法用数组创建
             *  3. 使用Stream的静态方法:of()、iterate()、generate()
             */
            //方式一: Collection.stream()方法用集合创建
            List<String> list = Arrays.asList("1", "2", "3", "4", "5", "6", "7", "8", "9");
            // 创建一个顺序流
            Stream<String> stream = list.stream();
            // 创建一个并行流
            Stream<String> stringStream = list.parallelStream();
            List<String> collect = stringStream.collect(Collectors.toList());
    
            //方式二: Arrays.stream(T[] array) 方法用数组创建
            int[] array = {1, 2, 3, 4, 5};
            IntStream stream1 = Arrays.stream(array);
            System.out.println(stream1.max().getAsInt());
    
    
            //方式三: 使用Stream的静态方法:of()、iterate()、generate()
            Stream<Integer> intStream = Stream.of(1, 2, 3, 4, 5, 6);
            Stream<Integer> stream2 = Stream.iterate(0, (x) -> x + 3).limit(4);
            // 0 3 6 9
            stream2.forEach(System.out::println);
    
            AtomicInteger m = new AtomicInteger(10);
            Stream<Integer> stream3 = Stream.generate(()-> m.getAndIncrement()).limit(3);
            //10 11 12
            stream3.forEach(System.out::println);
        }
    }
    

    Stream - 使用

    中间操作

    map

    map,可以将一个流的元素按照一定的映射规则映射到另一个流中;

    map,接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。

    filter

    filter,对流中的元素进行条件过滤,符合过滤条件的才能继续留在流中;

    filter,按照一定的规则校验流中的元素,将符合条件的元素提取到新的流中的操作。

    distinct

    distinct,去除流中的重复元素;

    sorted

    sorted(),自然排序,流中元素需实现Comparable接口;

    sorted(Comparator com),Comparator排序器自定义排序。

    limit

    limit,可以设置流的最大长度,超出的部分将被抛弃;

    skip

    skip,跳过流中的前n个元素,返回剩下的元素;

    flatMap

    flatMap,接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流;

    map只能把一个对象转换成另一个对象来作为流中的元素。而flatMap可以把一个对象转换成多个对象作为流中的元素。

    终结操作

    forEach

    forEach方法,通过 lambda 表达式的方式遍历集合中的元素;

    forEach,对流中的元素进行遍历操作,通过传入的参数去指定对遍历到的元素进行什么具体操作。

    count

    count,用来获取当前流中元素的个数;

    max&min

    max&min,可以用来或者流中的最值。

    collect

    collect,把当前流转换成一个集合;

    collect,把一个流收集起来,最终可以是收集成一个值也可以收集成一个新的集合;流不存储数据,那么在流中的数据完成处理后,需要将流中的数据重新归集到新的集合里。

    reduce

    reduce,把一个流缩减成一个值,能实现对集合求和、求乘积和求最值操作;

    reduce,对流中的数据按照你指定的计算方式计算出一个结果。

  • 相关阅读:
    RabbitMQ
    连接池,为什么要使用连接池?
    mac 安装arcanist
    感触
    UDP socket
    Servlet过滤器
    PL、SQL
    springmvc 文件上传实现(不是服务器的)
    注解spring
    excel工具类
  • 原文地址:https://www.cnblogs.com/HOsystem/p/16084816.html
Copyright © 2020-2023  润新知