尚硅谷|JDK新特性

Lamada表达式

示例代码

首先提供只有一个抽象方法的接口(函数式接口),这个可以自己定义,或者JDK8中国声明在java.util.function包下的函数式接口

@FunctionalInterface
public  interface MyFunctionalInterface {
    void method();
}

Lamada表达式案例

public class MyFunctionalInterfaceTest {
    @Test
    public void test(){
        MyFunctionalInterface mfi = ()->{
            System.out.println("未必要活在振奋里");
        };
        mfi.method();
    }
}

语法规则

->左边:Lamada形参列表,无参数时提供一对(),参数类型可以省略(类型推断),只有一个参数时可以省略括号

->右边:Lamda体,对应重写方法的方法体。如果只有一条执行语句,则{}可以省略,如果有return关键字,必须一并省略。参考如下代码

    //语法格式六:当 Lambda 体只有一条语句时,return 与大括号若有,都可以省略
    @Test
    public void test6() {

        Comparator<Integer> com1 = (o1, o2) -> {
            return o1.compareTo(o2);
        };

        System.out.println(com1.compare(12, 6));

        System.out.println("*****************************");
        Comparator<Integer> com2  = (o1,o2)->o1.compareTo(o2);

    }

理解

Lamada表达式既是接口的实现类对象(体现类万事万物皆对象),又是一个匿名函数。

方法引用与构造器引用

方法引用主要是对lamada表达式的进一步简化,具体使用情况如下:

Case1 :对象::实例方法

    @Test
    public void test1() {
        Consumer<String> con1 = new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        };
        con1.accept("hello");
        Consumer<String> consumer=s->System.out.println(s);
		Consumer<String> consumer1 = System.out::println;
    }

 其中Consumer接口如下,要记住参数和抽象方法,只接受不返回。

public interface Consumer<T> {
    void accept(T t);
}

 可以看到抽象方法中accpet和内部调用System.out对象的println方法的形参类别和返回值类型都相同,此时直接用println方法覆盖原有的。采用对象调方法的方式,参数类型可由接口的<String>推断。

总结:

要求:函数式接口中的抽象方法a与其内部实现时调用的对象的某个方法b的形参列表和返回值类型都相同(或一致)。
此时,可以考虑使用方法b实现对方法a的替换、覆盖。此替换或覆盖即为方法引用。

注意:此方法b是非静态的方法,需要对象调用。

case 2:类::静态方法


    //Comparator中的int compare(T t1,T t2)
    //Integer中的int compare(T t1,T t2)
    @Test
    public void test3() {
		Comparator<Integer> con1 = (o1,o2)->Integer.compare(o1,o2);
		System.out.println(con1.compare(23, 12));
		Comparator<Integer> con2 = Integer::compare;
        //下面这句属于第三种情况:类::实例方法,放在这里注意区分。
		Comparator<Integer> con3= Integer::compareTo;
	}

Integer类的compare方法结构如下:

public static int compare(int x, int y) {
        return (x < y) ? -1 : ((x == y) ? 0 : 1);
    }

Comparator接口结构如下

public interface Comparator<T> {

    int compare(T o1, T o2);
}

与Case1类似,参数列表和返回值相同,只不过这个方法是静态的,可以直接通过类调用而已。

case 3:类::实例方法

    //BiPredicate中的boolean test(T t1, T t2);
    //String中的boolean t1.equals(t2)
    @Test
    public void test6() {
		BiPredicate<String,String> biPredicate = (s1,s2)->s1.equals(s2);
		BiPredicate<String,String> biPredicate1 = String::equals;
		BiPredicate<String,String>biPredicate2 = String::equals;
	}

BiPredicate结构如下:

public interface BiPredicate<T, U> {

    /**
     * Evaluates this predicate on the given arguments.
     *
     * @param t the first input argument
     * @param u the second input argument
     * @return {@code true} if the input arguments match the predicate,
     * otherwise {@code false}
     */
    boolean test(T t, U u);

String类型的equals方法结构:public boolean equals(Object anObject)

以此代码为例:抽象方法test与equals的返回值类型相同,都是boolean。

同时test有两个参数(n个参数),equals有1个参数(n-1个参数),且抽象方法test的第一个参数作为equals方法的调用者,且抽象方法test后n-1个参数与equals的n-1个参数类型相同或一致(一致主要考虑自动装箱拆箱一类,比如Integer和int型),在此代码中后n-1个为空参。

注意:此方法b是非静态的方法,需要对象调用。但是形式上,写成对象所属的类。

构造器引用

调用哪个构造器主要取决于函数时接口的抽象方法的形参列表。

调用空参构造器:主要用的是supplier

        //1.
        Supplier<Employee> sup1 = new Supplier<Employee>() {
            @Override
            public Employee get() {
                return new Employee();
            }
        };

        System.out.println(sup1.get());

        //2.构造器引用
        Supplier<Employee> sup2 = Employee::new; //调用的是Employee类中空参的构造器
        System.out.println(sup2.get());
    }
        
        //Supplier接口形式,只返回不接受
        @FunctionalInterface
        public interface Supplier<T> {
            T get();
        }

调用一个参数构造器:主要用的是Function

	//Function中的R apply(T t)
    @Test
    public void test2(){
        //1.
        Function<Integer,Employee> func1 = new Function<Integer, Employee>() {
            @Override
            public Employee apply(Integer id) {
                return new Employee(id);
            }
        };

        System.out.println(func1.apply(12));
        //2.构造器引用
        Function<Integer,Employee> func2 = Employee :: new; //调用的是Employee类中参数是Integer/int类型的构造器
        System.out.println(func2.apply(11));

    }
    
    //Function接口结构:不要忘记指定返回值类型
     public interface Function<T, R> {
        R apply(T t);
     }

调用一个参数构造器:主要用的是BiFunction,两个参数确定一个结果

	//BiFunction中的R apply(T t,U u)
    @Test
    public void test3(){
        //1.
        BiFunction<Integer,String,Employee> func1 = new BiFunction<Integer, String, Employee>() {
            @Override
            public Employee apply(Integer id, String name) {
                return new Employee(id,name);
            }
        };

        System.out.println(func1.apply(10, "Tom"));
        //2.
        BiFunction<Integer,String,Employee> func2 = Employee::new;//调用的是Employee类中参数是Integer/int、String类型的构造器
        System.out.println(func2.apply(11, "Tony"));
    }
     
    //BiFunction接口结构
    public interface BiFunction<T, U, R> {
        R apply(T t, U u);
    }

Stream API使用

stream的创建

List<Employee> list = EmployeeData.getEmployees();
//通过集合        
Stream<Employee> stream = list.stream();
//通过数组
Integer[] arr = new Integer[]{1,2,3,4,5};
Stream<Integer> stream = Arrays.stream(arr);

  • 6
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值