Java工程师面试1000题149-Java8新特性之Lambda表达式

149、说一下Java8新特性之一的Lambda表达式

Lambda表达式允许你通过表达式来代替功能接口。 lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表达式或一个代码块)。Lambda表达式还增强了集合库。 Java SE 8添加了2个对集合数据进行批量操作的包: java.util.function 包以及java.util.stream 包。 流(stream)就如同迭代器(iterator),但附加了许多额外的功能。 总的来说,lambda表达式和 stream 是自Java语言添加泛型(Generics)和注解(annotation)以来最大的变化。 我们先从最简单的示例来介绍Lambda表达式。

①用Lambda表达式实现Runnable:

    @Test
    public void test1(){
        //使用Java8之前
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("使用Lambda表达式之前,需要这么写!");
            }
        }).start();
        //使用Lambda表达式
        new Thread(() -> System.out.println("使用Lambda表达式,只需要这一句话!")).start();
    }

上面这个例子向我们展示了Lambda表达式的语法,你可以使用Lambda表达式写出如下代码:

(params) -> expression

(params) -> statement

(params) -> {statement}

如果你的方法不对参数进行修改、重写,只是在控制台打印点东西的话,那么可以这样写:

() -> System.out.println("使用Lambda表达式,只需要这一句话!")

如果你的方法接收两个参数,那么可以写成这样:

(int even, int odd) -> even + odd

顺便提一句,通常都会把Lambda表达式内部变量的名字起的短一些,这样可以使代码看的更加简洁。

②使用Lambda表达式进行事件处理:

@Test
public void test2(){
    //使用Java8之前
    JButton show = new JButton("展示");
    show.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println("使用Lambda表达式之前");
        }
    });
    //使用Lambda表达式
    show.addActionListener((e -> {
        System.out.println("使用Lambda表达式");
    }));
}

③使用Lambda表达式对列表进行迭代

    @Test
    public void test3(){
        List features = Arrays.asList("hello","xidian","Lambda","google","youtube");
        //使用Java8之前
        for (Object feature : features){
            System.out.println(feature);
        }
        //使用Lambda表达式
        features.forEach(n -> System.out.println(n));
        //使用Java8的方法引用更方便,方法引用由:双冒号操作符标识
        features.forEach(System.out :: println);
    }

列表循环的最后一个例子展示了如何在Java8中使用方法引用,代码更加简洁。

④使用Lambda表达式和函数式接口Predicate:

 @Test
    public void test4(){
        List languages = Arrays.asList("Java","Scala","C++","Haskell","Lisp");

        System.out.print("J开头的语言有:");
        filter(languages,(str) -> str.startsWith("J"));

        System.out.print("a结束的语言有:");
        filter(languages,(str) -> str.endsWith("a"));

        System.out.print("所有语言:");
        filter(languages,(str) -> true);

        System.out.print("名字长度大于4的语言:");
        filter(languages,(str) -> str.length() > 4);
    }
    public void filter(List<String> names ,Predicate<String> predicate){
        for (String name : names){
            if (predicate.test(name)){
                System.out.println(name + " ");
            }
        }
    }

⑤使用Lambda表达式演示Map和Reduce

    @Test
    public void test5(){
        List<Integer> costBeforeTax = Arrays.asList(100,200,300,400,500);
        //不使用Lambda表达式为每个订单加上12%的税
        for (int cost : costBeforeTax){
            double v = cost + .12 * cost;
            System.out.println(v);
        }
        //使用Lambda表达式
        costBeforeTax.stream().map((cost) -> cost + .12 * cost).forEach(System.out :: println);
        //计算加税之后的总金额
        Double total = costBeforeTax.stream().map((c) -> c + c * .12).reduce((sum, c) -> sum += c).get();
        System.out.println("计算加税之后的总金额: " + total);
    }

在上面的例子中,可以看到map将集合类元素进行转换,reduce函数可以将所有值合并成一个。map和reduce操作是函数式编程的核心操作。

⑥对列表的每个元素应用函数

我们通常需要对列表的每个元素使用某个函数,例如逐一乘以某个数,初一某个数等,这些操作都很适合用map()方法,可以将转换逻辑以Lambda表达式的形式放在map函数里,就可以对集合中的各个元素进行转换了:

    @Test
    public void test6(){
        List<String> G7 = Arrays.asList("USA","Japan","France","Germany","Italy","U.K.","Cananda");
        //将元素中的小写字母转化为大写字母
        String collect = G7.stream().map(x -> x.toUpperCase()).collect(Collectors.joining(","));
        System.out.println(collect);
    }

⑦计算集合元素的最大值、最小值、总和及平均值

IntStream LongStream  DoubleStream 等流的类中,有一个非常有用的方法叫做summaryStatistics()。可以返回IntSummaryStatistics,LongSummaryStatistics, DoubleSummaryStatistics,描述流中元素的各种摘要数据。

    @Test
    public void test7() {
        List<Integer> primes = Arrays.asList(2,3,5,7,11,23,12,32,2,544);
        IntSummaryStatistics ststs = primes.stream().mapToInt((x) -> x).summaryStatistics();
        System.out.println("最大元素是:" + ststs.getMax());
        System.out.println("最小元素是:" + ststs.getMin());
        System.out.println("元素总和是:" + ststs.getSum());
        System.out.println("元素平均值是:" + ststs.getAverage());
        System.out.println("元素个数是:" + ststs.getCount());
    }

猜你喜欢

转载自blog.csdn.net/qq_21583077/article/details/88706645