JDK 8 函数式编程 Lambda表达式

简单应用

内部对象的简写

public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("鲁班1");
            }
        }).start();
		//效果与使用lambda表达式是一样的
        new Thread(() -> System.out.println("鲁班2")).start();
    }

Output:

鲁班1
鲁班2

传递函数作为参数

  • 使用Lambda表达式构成函数的参数 Fucntion
public static void main(String[] args) {
        System.out.println(doSomething(a->Integer.parseInt(a),"123"));
    }

    public static Integer doSomething(Function<String, Integer> function, String args) {
        return function.apply(args);
    }

Output:

123
  • 首先构建一个Apple
public class Apple {
    
    private Integer age;
    private String name;

    public Apple(Integer age, String name) {
        this.age = age;
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

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

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "Apple{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}
  • 最简单且熟悉的操作方案
public class AppleServer {
    private static ArrayList<Apple> apples = new ArrayList<Apple>();
    public static void main(String[] args) {
        apples.add(new Apple(1, "xia"));
        apples.add(new Apple(12, "jian"));
        apples.add(new Apple(123, "bing"));

        System.out.println(getAppleByName("xia"));
    }
    public static ArrayList<Apple> getAppleByName(String name) {
        ArrayList<Apple> res = new ArrayList<Apple>();

        for (Apple apple : apples) {
            if (apple.getName().equals(name)) {
                res.add(apple);
            }
        }
        return res;
    }



}
  • 使用Lambda函数构成选择逻辑 Predicate
public static void main(String[] args) {
        apples.add(new Apple(1, "xia"));
        apples.add(new Apple(12, "jian"));
        apples.add(new Apple(123, "bing"));
        
        System.out.println(getApple(a->a.getAge()<100 && a.getName().contains("a")));

    }
public static ArrayList<Apple> getApple(Predicate<Apple> predicate) {
        ArrayList<Apple> res = new ArrayList<>();

        for (Apple apple : apples) {
            if (predicate.test(apple)) {
                res.add(apple);
            }
        }
        return res;
    }

使用Stream优化遍历

public static ArrayList<Apple> getApple(Predicate<Apple> predicate) {
        ArrayList<Apple> res = new ArrayList<>();
        for (Apple apple : apples) {
            if (predicate.test(apple)) {
                res.add(apple);
            }
        }
        // 使用下面的stream可以直接遍历list
        res = (ArrayList<Apple>) apples.stream().filter(predicate).collect(Collectors.toList());
        return res;
    }

使用Lambda表达式实现简单的函数功能:apply

public class MyFunction {
    public static void main(String[] args) {
//        使用Lambda实现简单的函数
        Function<String, String> f = t -> "In Lambda "+t;
        System.out.println(f.apply("name"));
    }
}

自定义函数式接口

使用Lambda表达式实现接口函数

定义接口类

  • 使用@FunctionalInterface
  • 接口中只能存在唯一的非Object类的抽象方法
  • 如果想要添加其他的方法,那么需要添加default声明,同时该方法要在接口中被实现
@FunctionalInterface
public interface MyFunction {
    void sayHello();

    String toString();

    default void defaultFuntion(){

    }

}

使用Lambda表达式实现接口函数

public class MyFunction {
    public static void main(String[] args) {
        // 使用方法1 普通方法实现接口函数
        MyFunctionInterface myFunctionInterface1 = new MyFunctionInterface() {
            @Override
            public void sayHello(String name) {
                System.out.println(name+"Hello1");
            }
        };

        //使用方法2 Lambda表达式实现接口函数
        MyFunctionInterface myFunctionInterface2 = (name) -> {
            System.out.println(name+"Hello2");
        };

        myFunctionInterface1.sayHello("xia1");
        myFunctionInterface2.sayHello("xia2");
    }
}

引用

基于实例方法的引用

给一个实例的方法添加引用

public class ReferenceLambda {
    
    //    基于实例方法的引用
    public String sayHello(String name) {
        System.out.println(name + ":say Hello");
        return name + ":say Hello";
    }
    @Test
    public void test1() {
        ReferenceLambda referenceLambda = new ReferenceLambda();
        Function<String, String> f = referenceLambda::sayHello;
        f.apply("test1基于实例方法的引用");
    }
}

基于构造方法的引用

这个引用其实是一个对象,暂时还不知道怎么使用!

//    基于构造方法的引用
    public interface MyLove1 {
        String getLove();
    }

    @Test
    public void test2() {
        MyLove1 f = String::new; //使用String的构造方法是因为getLove的返回类型是String
        f.getLove();
    }

基于第一个参数的类型的引用

这个引用其实也是一个对象,其接口中被实现的方法是来自于接口函数中的第一个参数的类型的非静态方法

    //    基于第一个参数的类型的引用
    public interface MyLove3 {
        int getLove(String s1, String s2);
    }

    @Test
    public void test3() {
        //使用String是因为getLove的第一个参数是String类型
        //能够匹配上还有一个重要原因是compareTo的返回类型是int类型,与getLove返回类型相同
        //使用第一个参数s1的compareTo方法,并将s2作为compareTo的参数,返回值就是int类型
        MyLove3 f = String::compareTo;//非静态方法
        System.out.println(f.getLove("aa", "aa"));
    }

基于静态方法的引用

与上面一样,这个引用其实也是一个对象,其接口中被实现的方法是来自于接口函数中的第一个参数的类型的静态方法,而不是非静态方法。

    //    基于静态方法的引用
    public interface ToInteger {
        int toInt(String str);
    }
    @Test
    public void test4() {
        ToInteger toi = Integer::valueOf; //静态方法
        System.out.println(toi.toInt("1"));
    }

排序

  • 传统排序的方法
  • 使用Lambda表达式实现接口Comparator
  • 使用Stream加速,filter筛选,sorted排序
public class SortTest {
    public static void main(String[] args) {
        ArrayList<Apple> apples = new ArrayList<>();
        apples.add(new Apple(21, "xia"));
        apples.add(new Apple(12, "jian"));
        apples.add(new Apple(123, "bing"));


        //传统排序方法
        Collections.sort(apples, new Comparator<Apple>() {
            @Override
            public int compare(Apple o1, Apple o2) {
                return o1.getAge() - o2.getAge();
            }
        });


        //Lambda 排序
        Collections.sort(apples, (o1, o2) -> o1.getAge() - o2.getAge());

        //基于Stream排序
        ArrayList<Apple> res= (ArrayList<Apple>) apples.stream()
                .filter(a -> a.getName().contains("a")).
                sorted((o1, o2) -> o1.getAge() - o2.getAge()).
                collect(Collectors.toList());

        System.out.println(res);

    }
}

Stream

forEach

  • forEach方法可以将循环内部放进参数内
ArrayList<Apple> apples = new ArrayList<>();
apples.add(new Apple(21, "xia"));
apples.add(new Apple(12, "jian"));
apples.add(new Apple(123, "bing"));
for (Apple apple : apples) {
   System.out.println(apple);
}
apples.stream().forEach(System.out::println);
apples.stream().forEach((t)-> System.out.println(t)); // 这三种方法都可以
  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值