码迷,mamicode.com
首页 > 编程语言 > 详细

Java笔记:匿名方法

时间:2018-02-21 16:39:29      阅读:258      评论:0      收藏:0      [点我收藏+]

标签:局部变量   1.0   产生   uil   try   boolean   red   app   结果   

一、基础知识

lambda表达式本质上就是匿名方法,该方法不是独立执行的,而是用于实现由函数式接口定义的方法,函数式接口仅包含一个抽象方法的接口。

无参数lambda表达式。

技术分享图片
class Solution {
    interface MyNumber {
        double getValue();
    }

    public static void main(String[] args) {
        MyNumber number = () -> 100;
        System.out.println(number.getValue());
    }
}
View Code

带参数lambda表达式。

技术分享图片
class Solution {
    interface MyNumber {
        boolean isFactor(int a, int b);
    }

    public static void main(String[] args) {
        MyNumber number = (a, b) -> a % b == 0;
        System.out.println(number.isFactor(10, 5));
    }
}
View Code

块lambda表达式。

技术分享图片
class Solution {
    interface MyNumber {
        double getAvr(double... arr);
    }

    public static void main(String[] args) {
        MyNumber number = (arr) -> {
            double res = 0;
            for (double i : arr)
                res += i;
            res /= arr.length;
            return res;
        };
        double res = number.getAvr(1.0, 2.0, 3.0, 4.0, 5.0);
        System.out.println(res);
    }
}
View Code


二、泛型函数式接口

技术分享图片
class Solution {
    interface MyNumber<T extends Number> {
        T getAvr(T... arr);
    }

    public static void main(String[] args) {
        MyNumber<Double> number = (arr) -> {
            double res = 0;
            for (double i : arr)
                res += i;
            res /= arr.length;
            return res;
        };
        double res = number.getAvr(1.0, 2.0, 3.0, 4.0, 5.0);
        System.out.println(res);
    }
}
View Code


三、参数传递

可以lambda表达式作为参数传递给方法,为了将lambda表达式作为参数传递,接收lambda表达式的类型必须是与该lambda表达式兼容的函数式接口的类型。

技术分享图片
class Solution {
    interface MyString {
        String reverse(String s);
    }

    static String strOperate(MyString sf, String s) {
        return sf.reverse(s);
    }

    public static void main(String[] args) {
        String str = "Hello World";
        MyString sf = (s) -> {
            StringBuilder builder = new StringBuilder(s);
            return builder.reverse().toString();
        };
        System.out.println(strOperate(sf, str));
    }
}
View Code


四、异常

lambda表达式支持抛出异常,但是如果抛出经检查的异常,就必须与函数式接口的抽象方法throws语句所列出的异常兼容。

技术分享图片
class Solution {
    static class EmptyArrayException extends Exception {
        EmptyArrayException() {
            super("Empty Array");
        }
    }

    interface MyNumber {
        double getAvr(double... arr) throws EmptyArrayException;
    }

    public static void main(String[] args) {
        MyNumber number = (arr) -> {
            if (arr.length == 0)
                throw new EmptyArrayException();
            double res = 0;
            for (double i : arr)
                res += i;
            res /= arr.length;
            return res;
        };
        try {
            double res = number.getAvr();
            System.out.println(res);
        } catch (EmptyArrayException exc) {
            System.out.println(exc.getMessage());
        }
    }
}
View Code


五、变量捕获

lambda表达式中可以访问其外层作用域内定义的变量,但是这是会产生一种特殊情况,称为变量捕获。在这种情况下,lambda表达式只能使用实质上final的局部变量。final局部变量指的是第一次赋值之后值不能再发生变化的变量,这意味着lambda表达式不能修改外层作用域内的局部变量,即不能改变基本类型或者引用类型的数值,但是可以调用引用类型的方法。

 

六、方法引用

静态方法引用。

技术分享图片
class Solution {
    interface MyString {
        String reverse(String s);
    }

    static String strReverse(String s) {
        StringBuilder builder = new StringBuilder(s);
        return builder.reverse().toString();
    }

    static String strOperate(MyString sf, String s) {
        return sf.reverse(s);
    }

    public static void main(String[] args) {
        String str = "Hello World";
        System.out.println(strOperate(Solution::strReverse, str));//传递方法引用
    }
}
View Code

实例方法引用。

技术分享图片
class Solution {
    interface MyString {
        String reverse(String s);
    }

    String strReverse(String s) {
        StringBuilder builder = new StringBuilder(s);
        return builder.reverse().toString();
    }

    static String strOperate(MyString sf, String s) {
        return sf.reverse(s);
    }

    public static void main(String[] args) {
        Solution solution = new Solution();
        String str = "Hello World";
        System.out.println(strOperate(solution::strReverse, str));//传递方法引用
    }
}
View Code

泛型方法引用。

技术分享图片
class Solution {
    interface MyArray<T> {
        boolean contain(T[] arr, T x);
    }

    static <T> boolean arrContain(T[] arr, T x) {
        for (T i : arr)
            if (i.equals(x))
                return true;
        return false;
    }

    static <T> boolean arrOperate(MyArray<T> af, T[] arr, T x) {
        return af.contain(arr, x);
    }

    public static void main(String[] args) {
        Integer[] arr = {1, 2, 3, 4, 5};
        System.out.println(arrOperate(Solution::<Integer>arrContain, arr, 0));
    }
}
View Code

构造函数引用。

技术分享图片
interface MyInterface {
    MyClass constructor(int val);
}

class MyClass {
    private int val;

    MyClass(int val) {
        this.val = val;
    }

    MyClass() {
        val = 0;
    }

    int getVal() {
        return val;
    }
}

class Solution {
    public static void main(String[] args) {
        MyInterface mf = MyClass::new;//匹配MyClass(int val)
        MyClass mc = mf.constructor(100);
        System.out.println(mc.getVal());
    }
}
View Code

泛型构造函数引用。

技术分享图片
interface MyInterface<T> {
    MyClass constructor(T val);
}

class MyClass<T> {
    private T val;

    MyClass(T val) {
        this.val = val;
    }

    T getVal() {
        return val;
    }
}

class Solution {
    public static void main(String[] args) {
        MyInterface<Double> mf = MyClass::new;
        MyClass mc = mf.constructor(100.0);
        System.out.println(mc.getVal());
    }
}
View Code

 

七、预定义函数式接口

 通常我们不需要自己定义函数式接口,Java已经提供了一些预定义的函数式接口。

UnaryOperator<T> 对类型为T的对象应用一元运算并返回结果,方法名为apply。
BinaryOperator<T> 对类型为T的两个对象进行操作并返回结果,方法名为apply。
Consumer<T> 对类型为T的对象应用操作,方法名为accept。
Supplier<T> 返回类型为T的对象,方法名为get。
Function<T, R> 对类型为T的对象应用操作,并返回类型为R的对象,方法名为apply。
Predicate<T> 确定类型为T的对象是否满足某种约束,返回布尔值,方法名为test。

 

 

 

 

 

 

 

预定义函数式接口使用

技术分享图片
import java.util.function.BinaryOperator;

class Solution {
    public static void main(String[] args) {
        BinaryOperator<Integer> op = (a, b) -> a + b;
        System.out.println(op.apply(10, 100));//110
    }
}
View Code

 

Java笔记:匿名方法

标签:局部变量   1.0   产生   uil   try   boolean   red   app   结果   

原文地址:https://www.cnblogs.com/arseneyao/p/8455922.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!