java8新特性——函数式接口,方法,构造器,数组引用

package functional;
/*
定义:如果一个接口里面只声明了一个函数,就称为函数式接口
lambda表达式的本质:作为函数式接口的实例,必须依赖一类特别的对象类型——函数式接口
                   所以用匿名实现类表示的都可以用lambda表达式来写
Java.util.function 下也定义了Java8的函数式接口

函数式接口           内置抽象类           作用
1.Consumer<T>:      void accept(T t)    消费型
2.Supplier<T>:      T get()             返回一个对应的T对象
3.Function<T,R>:    R apply(T t)        对T的对象做一些处理,返回另一个R对象
4.Predicate<T>:     boolean test(T t)   测试T对象是否满足要求

@author zsben
@create 2020-01-10 19:13
*/

import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;

//函数式接口注解
@FunctionalInterface
interface MyInterface{
    void method1();
}

public class FunctionalTest {

    //第一类:消费性函数式接口 Consumer<T>
    public void happyTime(double money, Consumer<Double> consumer){
        consumer.accept(money);
    }
    @Test
    public void test1(){
        //这种写法是实现了Consumer<Double>的匿名子类对象
        happyTime(500, new Consumer<Double>() {
            @Override
            public void accept(Double aDouble) {
                System.out.println(aDouble);
            }
        });

        System.out.println("************************************");

        //通过lambda表达式实现函数式对象
        happyTime(400,money -> System.out.println(money));
    }

    //第二类:断言型函数式接口Predicate<T>
    //根据给定的规则,过滤集合中的字符串,此规则由Predicate的方法决定
    public ArrayList<String> filterString(List<String >list, Predicate<String> pre){
        ArrayList<String> filterList = new ArrayList<>();

        for(String s:list){
            if(pre.test(s))
                filterList.add(s);
        }

        return filterList;
    }
    @Test
    public void test2(){
        List<String> list = Arrays.asList("北京","南京","天津","东京","西京");

        //把名字里带有京的留下来
        List<String> filterStrs = filterString(list, new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.contains("京");
            }
        });
        System.out.println(filterStrs);

        System.out.println("********************************************");

        //这里其实就是用lambda把Predicate里的test(s)实现了
        List<String> filterStrs1 = filterString(list, s -> s.contains("京"));
        System.out.println(filterStrs1);
    }

}
package functional;
/*
方法引用:顾名思义就是引用一个方法
1.使用情景:当要传递给lambda体的操作,已经有实现的方法了,可以使用方法引用
2.方法引用:本质上就是lambda表达式,而lambda作为函数式接口的实例,
           所以方法引用,也是函数式接口的实例
3.使用格式:
    类::静态方法名
    类::非静态方法名
    对象::非静态方法名

4.使用要求:接口中的抽象方法形参列表和返回值的类型 与 方法引用的方法的形参列表,返回值都相同
@author zsben
@create 2020-01-10 19:58
*/

import org.junit.Test;

import java.io.PrintStream;
import java.util.Comparator;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

public class MethodreferencesTest {

    //情景一:对象::实例方法
    //Consumer中的void accept(T t)
    //PrintStream 中的 void println(T t)
    @Test
    public void test1() {
        Consumer<String> con1 = str -> System.out.println(str);
        con1.accept("北京");

        System.out.println("***************************");

        //System.out其实是一个打印流对象,有println(String s)这个方法
        PrintStream ps = System.out;
        Consumer<String> con2 = ps::println;//con2引用ps的方法println
    }

    //Supplier中的get()
    //Employee中的String getName()
    @Test
    public void test2(){
        Employee emp = new Employee(1001,"Tom",23,5600);

        Supplier<String> sup1 = ()->emp.getName();
        System.out.println(sup1.get());

        System.out.println("**********************************");

        Supplier<String> sup2 = emp::getName;
        System.out.println(sup2.get());
    }

    //情景二:类::静态方法
    //Comparator中的int compare(T t1,T t2)
    //Integer 中的int compare(T t1,T t2)
    @Test
    public void test3(){
        Comparator<Integer> com1 = (t1, t2) -> Integer.compare(t1,t2);
        System.out.println(com1.compare(1,2));

        System.out.println("******************************");

        Comparator<Integer> com2 = Integer::compare;
    }

    //Function中的 R apply(T t)
    //Math 中的long round(Double d)
    @Test
    public void test4(){
        Function<Double, Long> func1 = d -> Math.round(d);

        System.out.println("*****************************");

        Function<Double, Long> func2 = Math::round;//这个函数的形参,返回值必须一致
    }

    //情况三: 类::非静态方法
    //这种情况需要从lambda表达式对应的形参中抽出一个参数来当成该类的实例对象,并通过这个类调用后面的方法
    //Comparator中的int compare(T t1,T t2)
    //String中int t1.compareTo(t2)
    @Test
    public void test5(){
        Comparator<String> com1 = (s1,s2)->s1.compareTo(s2);
        System.out.println(com1.compare("123", "321"));

        System.out.println("-********************************");

        Comparator<String> com2 = String::compareTo;
        System.out.println(com2.compare("123", "321"));
    }
    //BiPredicate 中的boolean test(T t1,T t2)
    //String 中的boolean t1.equals(t2)
    @Test
    public void test6(){
        BiPredicate<String, String> pre1 = (s1,s2)->s1.equals(s2);
        System.out.println(pre1.test("abd","asd"));

        System.out.println("*********************************");

        BiPredicate<String, String> pre2 = String::equals;
        System.out.println(pre2.test("abd","asd"));
    }

    //Function 中的 R apply(T t)
    //Employee 中的 String getName();
    @Test
    public void test7(){
        Function<Employee,String> func1 = (emp)->emp.getName();
        System.out.println(func1.apply(new Employee(1, "zsben", 23, 25000)));

        System.out.println("*********************************");

        Function<Employee,String> func2 = Employee::getName;
        System.out.println(func2.apply(new Employee(1, "zsben", 23, 25000)));
    }
}
package functional;

/*
1.构造器引用
       和方法引用类似,函数式接口的抽象方法的形参列表和构造器和形参列表一致
       抽象方法的返回值类型即为构造器所属的类的类型
2.数组引用
    把数组看成是一个特殊的类,则写法和构造器引用一致
@author zsben
@create 2020-01-10 22:05
*/

import org.junit.Test;

import java.util.Arrays;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;

public class ConstructorTest {
    //构造器引用
    //Suppier中的T get()
    @Test
    public void test1(){
        Supplier<Employee> sup1 = () -> new Employee();
        System.out.println(sup1.get());

        Supplier<Employee> sup2 = Employee::new;
        System.out.println(sup2.get());
    }

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

        System.out.println("*********************************");

        Function<Integer,Employee> func2 = Employee::new;
        System.out.println(func2.apply(1));
    }

    //BiFunction中的R apply(T t,U u)
    @Test
    public void test3(){
        BiFunction<Integer,String,Employee> func1 = (id,name)->new Employee(id,name);
        System.out.println(func1.apply(1,"zsben"));

        System.out.println("*********************************");

        BiFunction<Integer,String,Employee> func2 = Employee::new;
        System.out.println(func1.apply(1,"zsben"));
    }

    //数组引用
    //Function中的R apply(T t)
    @Test
    public void test4(){
        Function<Integer,String[]> func1 = (length)->new String[length];
        String[] arr1 = func1.apply(6);
        System.out.println(Arrays.toString(arr1));

        System.out.println("*********************************");

        Function<Integer,String[]> func2 = String[]::new;
        String[] arr2=func2.apply(1);
        System.out.println(Arrays.toString(arr1));
    }
}

原文地址:https://www.cnblogs.com/zsben991126/p/12178647.html

时间: 2024-10-29 02:30:20

java8新特性——函数式接口,方法,构造器,数组引用的相关文章

Java8 新特性----函数式接口,以及和Lambda表达式的关系

这里来讲解一下Java8 新特性中的函数式接口, 以及和Lambda 表达式的关系.看到过很多不少介绍Java8特性的文章,都会介绍到函数式接口和lambda表达式,但是都是分别介绍,没有将两者的关系说明清楚,在这里,把自己的理解整理如下: 一.函数式接口: 函数式接口其实本质上还是一个接口,但是它是一种特殊的接口:SAM类型的接口(Single Abstract Method).定义了这种类型的接口,使得以其为参数的方法,可以在调用时,使用一个lambda表达式作为参数.从另一个方面说,一旦我

Java8新特性小结-接口与Lambda表达式

Java8的新特性相对于前版本(Java7)来说,主要体现在两个方面: 1.   接口定义与使用 2.   Lambda表达式对匿名内部类的简化使用. Java8新特性的具体表现如下: 1.在接口中的体现 (1)在接口中可以定义实体方法,但除原先的抽象方法外只能定义两种方法: A.公共的静态方法 如: package com.jasberyon.java8.interfacer; public interface InterfaceA { public static void sayHi(){

Java 8新特性-函数式接口

Java 8 引入的一个核心概念是函数式接口(Functional Interfaces). 通过在接口里面添加一个抽象方法,这些方法可以直接从接口中运行. 如果一个接口定义个唯一一个抽象方法,那么这个接口就成为函数式接口. 同时,引入了一个新的注解:@FunctionalInterface. 可以把他它放在一个接口前,表示这个接口是一个函数式接口. 这个注解是非必须的,只要接口只包含一个方法的接口,虚拟机会自动判断,不过最好在接口上使用注解 @FunctionalInterface 进行声明.

java8新特性四-默认方法

简介 Java 8 新增了接口的默认方法. 简单说,默认方法就是接口可以有实现方法,而且不需要实现类去实现其方法. 我们只需在方法名前面加个 default 关键字即可实现默认方法. 为什么要有这个特性? 首先,之前的接口是个双刃剑,好处是面向抽象而不是面向具体编程,缺陷是,当需要修改接口时候,需要修改全部实现该接口的类,目前的 java 8 之前的集合框架没有 foreach 方法,通常能想到的解决办法是在JDK里给相关的接口添加新的方法及实现.然而,对于已经发布的版本,是没法再给接口添加新方

Java8新特性:接口

Java接口本身没有任何实现,因为Java接口不涉及表象,而只描述public行为,所以Java接口比Java抽象类更抽象化. 以上是百度百科中对接口的定义,这个定义已经不准确. Java8对接口做了进一步的增强.1.在接口中可以添加使用 default 关键字修饰的非抽象方法. 2.接口里可以声明静态方法.interface名.静态方法名()直接时候用.(暴力吧) //定义一个接口,有三个方法. public interface IfTestIf {  public static void d

乐字节-Java8新特性-接口默认方法之Stream流(下)

接上一篇:<Java8新特性之stream>,下面继续接着讲Stream 5.流的中间操作 常见的流的中间操作,归为以下三大类:筛选和切片流操作.元素映射操作.元素排序操作: 操作 描述 筛选和切片 filter(T -> boolean):保留 boolean 为 true 的元素 limit(long n):返回前 n 个元素 skip(long n):去除前 n 个元素 distinct():去除重复元素,这个方法是通过类的 equals 方法来判断两个元素是否相等的 映射 map

JAVA8新特性——方法引用

JAVA9都要出来了,JAVA8新特性都没搞清楚,是不是有点掉队哦~ 在Lamda新特性的支持下,JAVA8中可以使用lamda表达式来创建匿名方法.然而,有时候我们仅仅是需要调用一个已存在的方法(如java中已经定义好的方法),在这时候java8新特性"方法引用"将会进一步简化操作(注意:需要有Lamda的支持). 方法引用的四种形式: 引用静态方法-->类名称::static 方法名称: 引用某个对象的实例的普通方法-->示例化对象::普通方法: 引用某个类型的任意对象

Android 使用Java8新特性之&quot;方法引用&quot;

前言 上一文:Android 使用Java8新特性之Lambda expression (附命令者模式简化) 说过lambda表达式,在android studio中的环境配置及应用.本文讲下Java8新特性之"方法引用". "方法引用",它其实可以看成lambda表达式的一种简写形式. 再回顾一下lambda表达式的应用场景:简化仅含单一抽象方法接口的调用 方法引用的4种形式 方法引用的符号形式,形如, [className | class-instance]::

JAVA8新特性——接口定义增强

JAVA9都要出来了,JAVA8新特性都没搞清楚,是不是有点掉队哦~ 接口定义增强 在JDK1.8以前,接口是定义的: 接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明.一个类通过继承接口的方式,从而来继承接口的抽象方法. 在JDK1.8之前,接口有如下特性: 接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错). 接口中