Java 8新特性(一)lambda表达式、函数式接口、方法引用、Optional类

1 lambda表达式:实现接口,并创建对象,可以理解为是匿名内部类的简化写法

说明:参数类型可以省略,如果是单参函数,括号也可以省略
语法:
①(参数表)->{方法实现}
②(参数表)-> 表达式 注:等价于return表达式
③ (参数表) -> 单句实现 注:return语句不能视为单句实现,对于无返回值的单句实现,{}也可以不写

基本使用样例

public class A {
    
    
    public static void main(String[] args) {
    
    
        ArrayList<Student> list = new ArrayList<>();
        list.add(new Student("aa",18));
        list.add(new Student("bb",19));
        list.add(new Student("cc",20));

        //匿名内部类实现
        Filter filter = new Filter() {
    
    
            @Override
            public boolean test(Student s) {
    
    
                return s.getAge() > 18;
            }
        };
        
        //lambda实现
        Filter f1 = t -> t.getAge()>18;

        List<Student> students = filterTest(list, filter);
        students.forEach(System.out::println);

    }
    
    private static List<Student> filterTest(List<Student> list, Filter filter){
    
    
        ArrayList<Student> students = new ArrayList<>();
        list.forEach(s->{
    
    
            if(filter.test(s)) students.add(s);
        });
        return students;
    }
}
interface Filter{
    
    
    boolean test(Student s);
}

class Student{
    
    
    private String name;
    private int age;

    public Student(String name, int age) {
    
    
        this.name = name;
        this.age = age;
    }

    public String getName() {
    
    
        return name;
    }

    public void setName(String name) {
    
    
        this.name = name;
    }

    public int getAge() {
    
    
        return age;
    }

    public void setAge(int age) {
    
    
        this.age = age;
    }

    @Override
    public String toString() {
    
    
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

1.1 函数式接口: 凡是只有一个方法的接口称为函数式接口

对于自定义接口,可以使用@FunctionalInterface注解来进行标注验证,如下图

@FunctionalInterface
interface Filter{
    
    
    boolean test(Student s);
}

我们常见的函数式接口,函数描述符左侧为入参,右侧为出参。

接口 函数描述符 方法名 备注说明
Predicate《T》 T-> boolean test
Conumer《T》 T- > void accept
Function《T,R》 T->R apply
Suppliier《T》 ()->T get 功能与call()相似
Bipredicate《T,R》 (T,R)-> boolean test
BiConsumer《T,R》 (T,R) ->void accept 如在遍历map时可用到
BiFunction《T,U,R》 (T,U)->R apply
UnaryOperator《T》 T>T apply 给的类型和返回值类型相同,是特殊的Function
BinaryOperator《T》 (T,T) -> T apply 给的类型和返回值类型相同,是特殊的Function

常见接口使用案例
① predicate

//匿名内部类实现
Predicate<Student> predicate = new Predicate<Student>() {
    
    
            @Override
            public boolean test(Student student) {
    
    
                return student.getAge() > 18;
            }
        };
//lambda形式
Predicate<Student> pred = t->t.getAge() > 18;

② Consumer

Consumer<Student> consumer = new Consumer<Student>() {
    
    
            @Override
            public void accept(Student student) {
    
    
                System.out.println(student);
            }
        };

Consumer<Student> consume = t-> System.out.println(t);

③ Function

public static void main(String[] args) {
    
    
        List<String> list = Arrays.asList("AAAA", "BBBB");

        //匿名内部类实现
        Function<String, String> function = new Function<String, String>() {
    
    
            @Override
            public String apply(String s) {
    
    
                return s.toLowerCase();
            }
        };
        //lambda实现
        Function<String, String> functio = s->s.toLowerCase();
                
         List<String> strings = filterTest(list, functio);
        strings.forEach(System.out::println);

    }

    private static List<String> filterTest(List<String> list,Function<String, String> function){
    
    
        ArrayList<String> students = new ArrayList<>();
        list.forEach(s->{
    
    
            students.add(function.apply(s));
        });
        return students;
    }

④ Supplier

 Supplier<String> supplier = new Supplier<String>() {
    
    
           @Override
           public String get() {
    
    
               return "aaaa";
           }
       };

Supplier<String> supplie = () -> "aaaaa";
System.out.println("AAA"+ supplier.get());

1.2 方法引用: 是lambda的特殊写法,从代码上更直观,最真实的还原程序员真实意图

常见的方法如下:

类型 lambda 方法引用
参数方法 (A arg0, B rest)-> arg0.method(rest) A::method
参数方法 (A a)-> a.method() A::method
静态方法 (args)-> ClassName.method(args) ClassName::method
其他对象方法 (args)-> expr.method(args) expr::method
构造方法 ()-> new Student Student::new
构造方法 (String s)-> new Student(s) Student::new

样例一:方法引用

public class Test {
    
    
    public static void main(String[] args) {
    
    
        I1 i1 = new I1() {
    
    
            @Override
            public void test(A a) {
    
    
                a.method();
            }
        };
        I1 test01 = (A a) -> a.method();
        I1 test02 = A::method;

        I2 i2 = new I2() {
    
    
            @Override
            public void test(A a, String b) {
    
    
                a.method(b);
            }
        };
        I2 test03 = (A a,String b) -> a.method(b);
        I3 test04 = A::method;

        I3 i3 = new I3() {
    
    
            @Override
            public void test(A a, String b, String c) {
    
    
                a.method(b, c);
            }
        };
        I3 test05 = (A a, String b, String c) -> a.method(b,c);
        I3 test06 = A::method;

        I5 i5 = new I5() {
    
    
            @Override
            public void test(String s) {
    
    
                Integer.parseInt(s);
            }
        };
        I5 test07 = s -> Integer.parseInt(s);
        I5 test08 = Integer::parseInt;

        
    }
}
class A {
    
    
    public void method(){
    
    }
    public void method(String a){
    
    }
    public void method(String a ,String b){
    
    }
}
interface I1{
    
    
    void test(A a);
}
interface I2{
    
    
    void test(A a ,String b);
}
interface I3{
    
    
    void test(A a ,String b, String c);
}
interface I4{
    
    
    void test(String s ,A a);
}
interface I5{
    
    
    void test(String s);
}

案例二:构造方法

public class Test {
    
    
    public static void main(String[] args) {
    
    
        Q q = new Q() {
    
    
            @Override
            public Student method() {
    
    
                return new Student();
            }
        };

        Q test01 = () -> new Student();
        Q test02 = Student::new;

        W w = new W() {
    
    
            @Override
            public Student method(String s) {
    
    
                return new Student(s);
            }
        };
        W test03 = s ->new Student(s);
        W test04 = Student::new;

        Supplier<Student> supplier = Student::new;
        Function<String,Student> function = Student::new;
    }
}
interface Q{
    
    
    Student method();
}
interface W{
    
    
    Student method(String s);
}
class Student{
    
    
    public Student() {
    
    
        System.out.println("A");
    }
    public Student(String a) {
    
    
        System.out.println("B");
    }
    public Student(String a,String b) {
    
    
        System.out.println("c");
    }
}

案例三:比较器

public class Test {
    
    
    public static void main(String[] args) {
    
    
        ArrayList<Employee> list = new ArrayList<>();
        list.add(new Employee("aa",11,100.0));
        list.add(new Employee("cc",33,300.0));
        list.add(new Employee("bb",22,200.0));

        Comparator<Employee> comparator = Comparator.comparingInt(new ToIntFunction<Employee>() {
    
    
            @Override
            public int applyAsInt(Employee value) {
    
    
                return value.getAge();
            }
        });
        Comparator<Employee> comparator1 = Comparator.comparingInt(value -> value.getAge());
        Comparator<Employee> comparator2 = Comparator.comparingInt(Employee::getAge);
        Comparator<Employee> comparator3 = Comparator.comparing(Employee::getName);
        Comparator<Employee> comparator4 = Comparator.comparingDouble(Employee::getSalary);
        //两个条件的比较
        Comparator<Employee> comparator5 = comparator3.thenComparing(comparator4);
        
        list.sort(comparator4.reversed());

        list.forEach(System.out::println);
    }
}
class Employee{
    
    
    String name;
    int age;
    double salary;

    public Employee() {
    
    
    }

    public Employee(String name, int age, double salary) {
    
    
        this.name = name;
        this.age = age;
        this.salary = salary;
    }

    public String getName() {
    
    
        return name;
    }

    public void setName(String name) {
    
    
        this.name = name;
    }

    public int getAge() {
    
    
        return age;
    }

    public void setAge(int age) {
    
    
        this.age = age;
    }

    public double getSalary() {
    
    
        return salary;
    }

    public void setSalary(double salary) {
    
    
        this.salary = salary;
    }

    @Override
    public String toString() {
    
    
        return "Employee{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", salary=" + salary +
                '}';
    }
}

1.3 Optional: 针对的是空指针异常的,可避免空指针异常

一、创建Optional
①创建空值:empty()

Optional<Object> empty = Optional.empty();

②创建非空值:of(T value)

Optional<String> optional = Optional.of("AAA");

③创建Optional对象,允许null值:ofNullable(T value)

Optional<Object> optionalO = Optional.ofNullable(new Employee());

二、访问Optional
①判断值是否存在:isPresent()

Optional<String> optional = Optional.of("AAA");
System.out.println(optional.isPresent());

②获取值,空值抛异常:get()

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

③获取值,如果无值则取默认值:orElse(T value)

Optional<Object> empty = Optional.empty();
System.out.println(empty.orElse("BBB"));

④如果值存在,则消费值,值不存在,不抛空指针异常:ifPresent(Consumer consumer)

 optional.ifPresent(System.out::print);

使用样例:

传统方式:会抛空指针异常,如为了避免空指针异常,需要进行频繁的if判断

public class Test {
    
    
    public static void main(String[] args) {
    
    
        Man man = new Man();
        String name = man.woman.name;
        System.out.println(name);
    }
}
class Man{
    
    
    String name;
    Woman woman;
}
class Woman{
    
    
    String name;
    public void method(){
    
    }
}

Optional:不会抛空指针异常,避免了频繁的if判断

public class Test {
    
    
    public static void main(String[] args) {
    
    
        Man man = new Man();

        Optional<Woman> woman = man.wife;
        String name = woman.get().name;
        System.out.println(name);

    }
}
class Man{
    
    
    String name;
    Optional<Woman> wife = Optional.ofNullable(new Woman());
    public Optional<Woman> getWife(){
    
    
        return wife;
    }
}
class Woman{
    
    
    String name;
    public void method(){
    
    

    }
}

猜你喜欢

转载自blog.csdn.net/qq_44962429/article/details/114890217