Java8新特性 Lambda、Function和Stream

Lambda

定义

Lambda表达式主要用来定义行内执行的方法类型接口,例如,一个简单方法接口。在上面例子中,我们使用各种类型的Lambda表达式来定义MathOperation接口的方法。然后我们定义了sayMessage的执行。
理解:一些简单的接口 不用去写他的实现 通过lambde做一些简单的处理 lambde中的参数需要和对应接口中一致

public class LambdaTest {
    public static void main(String[] args) {
        LambdaTest lambdaTest = new LambdaTest();

        /**
         * 表达式使用{}必须要加return返回信息
         */
        MathOperator addtion = (int a, int b) -> {
            return a + b;
        };

        MathOperator subtraction = (int a, int b) -> a - b;

        MathOperator division = (a, b) -> a / b;

        System.out.println("10 + 5 = " + lambdaTest.operate(10, 5, addtion));
        System.out.println("10 - 5 = " + lambdaTest.operate(10, 5, subtraction));
        System.out.println("10 / 5 = " + lambdaTest.operate(10, 5, division));

        SentMessage sentMessage = mes -> System.out.println("我是" + mes);
        sentMessage.sayMessage("成龙");

    }

    interface MathOperator {
        /**
         * 用于计算两个数的操作
         *
         * @param a
         * @param b
         * @return
         */
        int operation(int a, int b);
    }

    interface SentMessage {
        /**
         * 发送消息
         *
         * @param message
         */
        void sayMessage(String message);
    }

    private int operate(int a, int b, MathOperator mathOperator) {
        return mathOperator.operation(a, b);
    }

}

变量作用域

lambda 表达式只能引用标记了 final 的外层局部变量,这就是说不能在 lambda 内部修改定义在域外的局部变量

int num = 1;  
Converter<Integer, String> s = (param) -> System.out.println(String.valueOf(param + num));
s.convert(2);
num = 5;  
//报错信息:Local variable num defined in an enclosing scope must be final or effectively 
 final

Function

JDK8提供的多种内置的函数式接口

typeparam
Consumer < T >接收T对象,不返回对象
Predicate < T >接收T对象,返回Boolean对象
Function < T,R >接收T对象,返回R对象
Supplier< T >不接收对象,返回T对象(例如工厂)
UnaryOperator接收T对象,返回T对象
BinaryOperator接收两个T对象,返回T对象

在这些接口中有一些方法

       Function<Integer, Integer> name = e -> e * 2;
        Function<Integer, Integer> square = e -> e * e;
        int value = name.andThen(square).apply(3);
        System.out.println("andThen value=" + value);
        int value2 = name.compose(square).apply(3);
        System.out.println("compose value2=" + value2);

apply() 将Function对象应用到输入的参数上,然后返回计算结果。
andthen() 先执行当前函数的apply(),在执行内部的apply方法,例子结果为36
compose 先执行内部apply,在执行外部apply,例子结果18

示例

	@Test
    /**
     * 没有输入参数,返回一个T类型的值
     */
    public void supplierTest() {
        Supplier<Integer> s = () -> {
            return 1 + 1;
        };

        Integer integer = s.get();
        log.info("结果" + integer);//结果2
    }

    /**
     * 接收一个T类型的参数,并且没有返回值。
     */
    @Test
    public void consumerTest() {
        Consumer<Integer> print = System.out::println;
        Consumer<Integer> printPlusSelf = x -> System.out.println(x + x);

        //注意:这里先输出10,在输出20
        print.andThen(printPlusSelf).accept(10);
    }

    /**
     * 接收T返回boolean
     */
    @Test
    public void predicateTest() {
        Predicate<String> predicate = x -> {
            return x.equals("predicate");
        };
        boolean test1 = predicate.test("666");
        boolean test2 = predicate.test("predicate");
        boolean test3 = predicate.or(m -> m.equals("666")).test("666");
        boolean test4 = predicate.and(m -> m.equals("666")).test("666");
        System.out.println(test1);//false
        System.out.println(test2);//true
        System.out.println(test3);//true
        System.out.println(test4);//false
    }

    /**
     * 接收T返回R
     * andthen 先apply,再内部apply
     * compose相反
     */
    @Test
    public void functionTest() {
        Function<String, Integer> function = x -> x.equals("10") ? 0 : Integer.parseInt(x) + 1;
        Integer apply = function.apply("10");
        System.out.println(apply);//0
        Integer apply1 = function.andThen(x -> x * x + 1).apply("5");//37
        System.out.println(apply1);
        Integer apply2 = function.compose(String::valueOf).apply("5");//6
        System.out.println(apply2);
    }

    /**
     * 接受两个T,返回一个T
     */
    @Test
    public void binaryOperatorTest(){
        BinaryOperator<String> binaryOperator = (x,y) -> x+y;
        String apply = binaryOperator.apply("我是", "大坏蛋");
        System.out.println(apply);//我是大坏蛋
    }

Stream

集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。
理解: 就是操作数组或者集合 并对他们进行处理

例如 详情请查看链接

anyMatch()函数,用于检查列表中的任何元素是否满足给定条件。

forEach

Stream 提供了新的方法 ‘forEach’ 来迭代流中的每个数据。以下代码片段使用 forEach 输出了10个随机数:

Random random = new Random();
random.ints().limit(10).forEach(System.out::println);

flatMap()

将多个集合或者流合为一个集合
比如将list转为list
map.values是一个流Stream,所以现在是List<Stream< String>>
我们可以将多个流合并使用flatMap(List::stream),就成了Stream< String>
再转成list ,collect.(Collects.tolsit())
;
collect中使用Collectors对集合进行操作
https://www.jianshu.com/p/7eaa0969b424
.collect(Collectors.toCollection(LinkedList::new));

示例代码

public class Test {

    public static void main(String[] args) {
        List<Integer> num = Arrays.asList(1, 2, 3, 4, 7, 6, 9, 8, 0, 99);
        List<String> strings = Arrays.asList("qw", "er", "ty", "yu", "io", "pa");

        //找出大于5的元素个数
        long count = num.stream().filter(n -> n > 5).count();
        System.out.println("大于5的个数"+count);

        //为每个元素 平方 找出大于15的  并排序  再输出 前五个
        num.stream().map(x->x*x).filter(x->x>15).sorted().limit(5).forEach(System.out::println);

        //将不为空且不含e的元素 合并  单词之间用,隔开
        String e = strings.stream().filter(string -> !string.isEmpty() && !string.contains("e")).collect(Collectors.joining(","));
        System.out.println("将不为空且不含e的元素 合并  单词之间用,隔开为"+e);
    }
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值