VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > Java教程 >
  • java8 (jdk 1.8) 新特性——Lambda

java8 (jdk 1.8) 新特性 ——初步认识

http://mp.weixin.qq.com/s?__biz=Mzk0NTMwMjg2MA==&mid=2247484530&idx=1&sn=c7e3bb0da9d4d3728f079c01498d0e82&chksm=c3163851f461b1478f0c8e6406581ecea00bbe9e48d7eba7b5301d94dda802b42e09f10300ff&scene=21#wechat_redirect

 

1. 什么是lambda?

目前已知的是,有个箭头  ->  

说一大段官方话,也没有任何意义

我们直接看代码:

之前我们创建线程是这样的

复制代码
Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("run。。。。。。");
            }
        };
        runnable.run();
复制代码

用lambda:

1
2
Runnable run2 = () -> System.out.println("run。。。。。。");
    run2.run();

  

 

 

 

是不是感觉特别离谱,看不懂

别急,还有更离谱的

很常见的一个例子,比较两个整数的大小

之前是这样写的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    Comparator<Integer> myCom = new Comparator<Integer>() {
        @Override
        public int compare(Integer o1, Integer o2) {
            return Integer.compare(o1, o2);
        }
    };
 
    int compare = myCom.compare(12, 20);
    int compare1 = myCom.compare(20, 12);
    int compare2 = myCom.compare(20, 20);
    System.out.println(compare);
    System.out.println(compare1);
    System.out.println(compare2);
}

  

用lambda:

1
2
3
4
5
6
7
8
Comparator<Integer> myCom = (o1, o2) -> Integer.compare(o1, o2);
 
int compare = myCom.compare(12, 20);
int compare1 = myCom.compare(20, 12);
int compare2 = myCom.compare(20, 20);
System.out.println(compare);
System.out.println(compare1);
System.out.println(compare2);

  甚至还可以这样 (这个是方法引用)

1
2
3
4
5
6
7
8
Comparator<Integer> myCom = Integer::compare;
 
       int compare = myCom.compare(12, 20);
       int compare1 = myCom.compare(20, 12);
       int compare2 = myCom.compare(20, 20);
       System.out.println(compare);
       System.out.println(compare1);
       System.out.println(compare2);

  

第一个数比第二个数    

大 :返回 1

小:返回 -1

相等:返回 0 

 

 

 

刚接触是不是黑人问号,这是什么玩意 

很好,到这,你认识到了lambda 一个缺点,可阅读性差 ,优点 代码简洁

小结:看到 -> lambda           看到 : : 方法引用

 

2.  lamdba 语法

 

 

  • 基本语法 

 1.  箭头操作符  ->  或者叫做lambda 操作符

 2.  箭头操作符将lambda 表达式拆分成两部分 

      左侧:Lambda 表达式的参数列表 

      右侧:Lambda 表达式中所需执行的功能  , 即 Lambda 体

 

 

3. 语法格式

 

语法格式1:无参数,无返回值 

  • 1
    () -> system.out.println("Hello Lambda")  

      

    前边线程的那个例子就是

 

语法格式2:有一个参数 无返回值

1
(x)-> System.out.println(x);

  

若只有一个参数可以省略不写

 

 

1
x-> System.out.println(x);

  

 之前的写法,没有使用lambda

1
2
3
4
5
6
7
8
Consumer<String> consumer = new Consumer<String>() {
           @Override
           public void accept(String s) {
               System.out.println("输出的值:"+s);
           }
       };
       
       consumer.accept("今天不想emo了");

  

 使用lambda 

1
2
3
Consumer<String> consumer = s -> System.out.println("输出的值:"+s);
 
       consumer.accept("今天不想emo了");

 

语法格式3:有两个以上参数 ,并且lambda体有多条语句,有返回值

1
2
3
4
Comparator<Integer> myCom = (o1, o2) -> {
         System.out.println("其他语句");
         return Integer.compare(o1, o2);
     };

  

语法格式4  lambda体中只有一条语句,return 和 大括号都可以省略不写

1
Comparator<Integer> com  =(x,y)-> Integer.compare(x,y);

  有没有发现所有的参数,都没有参数类型,之前我们写函数的时候可是要带上参数类型的

 

语法格式5  lambda表达式参数列表的数据类型可以省略不写,因为JVM编译器通过上下文编译推断出数据类型——类型推断 

 

 

 4. 函数式接口

不管上面哪一种语法格式,lambda都是需要函数式接口的支持

 函数式接口:接口中只有一个抽象方法的接口 称为函数式接口

可以使用一个注解@FunctionalInterface 修饰,可以检查是否是函数式接口

我们可以看看Runnable  接口 的源码

完成的接口类代码如下

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/*
 * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
 *  ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms
 /
 
package java.lang;
/**
 * The <code>Runnable</code> interface should be implemented by any
 * class whose instances are intended to be executed by a thread. The
 * class must define a method of no arguments called <code>run</code>.
 * <p>
 * This interface is designed to provide a common protocol for objects that
 * wish to execute code while they are active. For example,
 * <code>Runnable</code> is implemented by class <code>Thread</code>.
 * Being active simply means that a thread has been started and has not
 * yet been stopped.
 * <p>
 * In addition, <code>Runnable</code> provides the means for a class to be
 * active while not subclassing <code>Thread</code>. A class that implements
 * <code>Runnable</code> can run without subclassing <code>Thread</code>
 * by instantiating a <code>Thread</code> instance and passing itself in
 * as the target.  In most cases, the <code>Runnable</code> interface should
 * be used if you are only planning to override the <code>run()</code>
 * method and no other <code>Thread</code> methods.
 * This is important because classes should not be subclassed
 * unless the programmer intends on modifying or enhancing the fundamental
 * behavior of the class.
 *
 * @author  Arthur van Hoff
 * @see     java.lang.Thread
 * @see     java.util.concurrent.Callable
 * @since   JDK1.0
 */
@FunctionalInterface
public interface Runnable {
    /**
     * When an object implementing interface <code>Runnable</code> is used
     * to create a thread, starting the thread causes the object's
     * <code>run</code> method to be called in that separately executing
     * thread.
     * <p>
     * The general contract of the method <code>run</code> is that it may
     * take any action whatsoever.
     *
     * @see     java.lang.Thread#run()
     */
    public abstract void run();
}

  

 

 

 

 

 

可以看到这里面就只有一个实现,有一个注解@FunctionalInterface ,说明它就是一个函数式接口,就可以进行lambda简写

 

来看 Comparator 也是一样 有@FunctionalInterface注解

 

 

 

 

 

 

 

 

 

这里可能就会有疑问,这边明明是有两个抽象方法,怎么是函数式接口呢?

 

别急 !!可以看到这边的注释, 说明这个equals 是 重写了超类 的 equals,本质上是对object 的重写,官方定义这样的抽象方法是不会被定义到 抽象接口数的 ,因此实际上只有一个抽象方法

 

 

 

 

 

 我们自己可以试着定义 函数式接口,很简单

 

 

1
2
3
4
5
6
7
8
9
package com.test1.demo;
 
 
@FunctionalInterface
public interface MyFunc {
 
    void  method();
    
}

  

 

 好了,如果,写两个抽象接口会怎样?

 

 

 

 

 

可以看到注解报错了,所以注解用来校验作用就在这

 

 重申一遍,函数式接口:接口中只有一个抽象方法的接口 称为函数式接口

注解只是拿来校验的,方便我们一看就知道这是一函数式接口类,不然还得数个数,验证一下是不是只有一个

 

 现在我也重写 equals ,可以看到并没有报错

 

 

 

 5. java8 中内置四大核心函数式接口 

  •   Consumer<T> 消费型接口 

1
2
3
4
5
6
7
8
9
10
//Consumer  消费型接口
   @Test
   public void testConsumer() {
       cosumer(1000, (m) -> System.out.println("星期一" + m));
       // 星期一1000.0
   }
 
   public void cosumer(double m, Consumer<Double> con) {
       con.accept(m);
   }

  

 

  •  供给型接口  supplier<T>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Test
    public void testSupplier() {
        List<Integer> numList = getNumList(10, () -> (int) (Math.random() * 100));
        for (Integer integer : numList) {
            System.out.println(integer); //100 以内10位随机整数
        }
    }
 
    // 需求:产生指定个数的整数放入集合中
    public List<Integer> getNumList(int num, Supplier<Integer> su) {
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < num; i++) {
            Integer integer = su.get();
            list.add(integer);
        }
        return list;
    }

  

 

  •  Function<T,R> 函数型接口

1
2
3
4
5
6
7
8
9
10
11
@Test
   public void  FunctioStr(){
       String c = getFunction("sbjikss", str -> str.toUpperCase());
       System.out.println(c); //SBJIKSS
       String sub = getFunction("sbjikss", str -> str.substring(2, 3));
       System.out.println(sub);//j
   }
 
   public  String  getFunction( String str, Function<String,String> f) {
       return f.apply(str);
   }

  

 

  • 断言型接口 Predicate<T>  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public  void  tetPre(){
        List<String> list = Arrays.asList("Hello","sss","xxxx","sjjss");
       List<String> list1 = filterStr(list, (pre) -> pre.length() > 3);
       for (String s : list1) {
           System.out.println(s);  // Hello xxxx  sjjss
       }
   }
  //需求:将满足条件字符串放入集合中
   public  List<String>  filterStr(List<String> old , Predicate<String> pre ){
       List<String> newList  = new  ArrayList<>();
       for (String str : old) {
           if (pre.test(str)){
              newList.add(str);
           }
       }
       return newList;
   }

  

 感谢阅读!!!

出处:https://www.cnblogs.com/zeroll/p/16904162.html


相关教程