前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Lambda表达式

Lambda表达式

作者头像
后端码匠
发布2019-09-02 16:52:07
5570
发布2019-09-02 16:52:07
举报
文章被收录于专栏:后端码匠后端码匠

Lambda表达式

五、Lambdad表达式综合案例:

废话不多说,上代码(讲解在代码注释中):

5.1、集合排序

代码语言:javascript
复制
package com.zhangshangbiancheng.exercise;

import com.zhangshangbiancheng.data.Person;

import java.util.ArrayList;
import java.util.Comparator;

public class Exercise1 {
    //集合排序
    //ArrayList<>
    public static void main(String[] args) {
        //需求:已知在一个ArrayList中有若干个Person对象,将这些Person对象按照年龄降序排列
        ArrayList<Person> list = new ArrayList<>();

        list.add(new Person("掌上编程1",1));
        list.add(new Person("掌上编程2",12));
        list.add(new Person("掌上编程3",13));
        list.add(new Person("掌上编程4",24));
        list.add(new Person("掌上编程5",56));
        list.add(new Person("掌上编程6",65));
        list.add(new Person("掌上编程7",43));
        list.add(new Person("掌上编程8",34));

        list.sort((o1,o2) ->o2.age-o1.age);


        //list.sort(Comparator.comparing());                int compare(T o1, T o2);
        System.out.println(list);
    }
}

5.2、TreeSet:

代码语言:javascript
复制
package com.zhangshangbiancheng.exercise;

import com.zhangshangbiancheng.data.Person;

import java.util.TreeSet;

public class Exercise2 {
    public static void main(String[] args) {
        //TreeSet
        //无参数创建会报错 java.lang.ClassCastException: com.zhangshangbiancheng.data.Person cannot be cast to java.lang.Comparable
        //修改 :使用Lambda表达式来实现Comparator接口,并实例化一个TreeSet对象     TreeSet<Person> set = new TreeSet<>((o1, o2) -> o2.age-o1.age);
        //若为为要同元素  则之显示出一个    比较为零做处理避免此情况发生

        TreeSet<Person> set = new TreeSet<>((o1, o2) -> {
            if (o1.age >= o2.age){
                return -1;
            }
            else {
                return 1;
            }
        });
        set.add(new Person("掌上编程1",1));
        set.add(new Person("掌上编程2",12));
        set.add(new Person("掌上编程3",13));
        set.add(new Person("掌上编程4",24));
        set.add(new Person("掌上编程5",56));
        set.add(new Person("掌上编程6",65));
        set.add(new Person("掌上编程7",43));
        set.add(new Person("掌上编程8",34));
        set.add(new Person("掌上编程9",12));
        System.out.println(set);

    }

}

5.3、集合的遍历:

代码语言:javascript
复制
package com.zhangshangbiancheng.exercise;

import com.zhangshangbiancheng.data.Person;

import java.util.ArrayList;
import java.util.Collections;


public class Exercise3 {
    public static void main(String[] args) {
        //集合的和遍历

        ArrayList<Integer> list = new ArrayList<>();

        Collections.addAll(list, 1, 2, 3, 4);

        //将集合中每一个元素都带入到方法accept中     void accept(T t);
        list.forEach(System.out::println);

        //输出集合中所有的偶数
        list.forEach(ele -> {
            if (ele % 2 == 0){
                System.out.println(ele);
            }
        });

    }


}

5.4、删除集合中元素:

代码语言:javascript
复制
package com.zhangshangbiancheng.exercise;

import com.zhangshangbiancheng.data.Person;

import java.util.ArrayList;
import java.util.Iterator;

public class Exericse4 {
    public static void main(String[] args) {

        //需求:删除集合中的元素

        ArrayList<Person> list = new ArrayList<>();

        list.add(new Person("掌上编程1",1));
        list.add(new Person("掌上编程2",12));
        list.add(new Person("掌上编程3",13));
        list.add(new Person("掌上编程4",24));
        list.add(new Person("掌上编程5",56));
        list.add(new Person("掌上编程6",65));
        list.add(new Person("掌上编程7",43));
        list.add(new Person("掌上编程8",34));

        //删除几何中年龄>10岁的元素  迭代器
        Iterator<Person> it = list.iterator();
        while (it.hasNext()){
            Person ele = it.next();
            if (ele.age>10){
                it.remove();
            }
            System.out.println(list);
        }

        //Lambda实现
        //将集合
        list.removeIf(ele ->ele.age>10);


    }
}

5.5、线程相关:

代码语言:javascript
复制
package com.zhangshangbiancheng.exercise;

public class Exericse5 {
    public static void main(String[] args) {
        Thread t = new Thread(() -> {
            for (int i = 0;i<100;i++){
                System.out.println(i);
            }
        });

        t.run();
    }


    //

}

六、闭包

代码语言:javascript
复制
package com.zhangshangbiancheng.closure;

import java.util.function.Supplier;

public class ClosureDemo {
    public static void main(String[] args) {
        //闭包   提升变量的生命周期
        int n = getNumber().get();
        System.out.println(n);
    }

    private static Supplier<Integer> getNumber(){
        int num = 10;
        return ()->{
            return num;
        };
    }
}
代码语言:javascript
复制
package com.zhangshangbiancheng.closure;

import java.util.function.Consumer;

public class ClosureDemo2 {
    public static void main(String[] args) {
        //此时a  是final  运行时默认添加  一定是常量
        int a = 10;

        Consumer<Integer> c = ele->{
            System.out.println(a);
        };

        c.accept(a);
    }
}

总结:

什么时候可以使用Lambda

Lambda表达式是可以在函数式接口上使用的。函数式接口就是只定义一个抽象方法的接口。比如:

代码语言:javascript
复制
public interface Predicate<T>{
    boolean test (T t);
}

public interface Comparator<T>(){
    int compare(T o1,T o2);
}

public interface Runnable{
    void run();
}

其实,Lambda表达式允许你直接以内联的形式为函数式接口的抽象方法提供实现,并把整个表达式作为函数式接口的实例(确切来说,是函数式接口的一个具体实现的实例)。

Lambda表达式的具体使用

如果我们想要从一个文件中读取一行所需的内容,可以定义这样的方法:

代码语言:javascript
复制
public static String processFile() throws IOException {
    try (BufferedReader br = 
            new BufferedReader(new FileReader("data.txt"))){
        return br.readLine();
    }
}

Lambda表达式的具体使用

如果我们想要从一个文件中读取一行所需的内容,可以定义这样的方法:

代码语言:javascript
复制
public static String processFile() throws IOException {
    try (BufferedReader br = 
            new BufferedReader(new FileReader("data.txt"))){
        return br.readLine();
    }
}

那如果要读取两行呢,这时候我们就应该记起来行为参数化。

使用函数式接口来传递行为

代码语言:javascript
复制
public static String processFile(BufferedReaderProcessor p) throws Exception{
        try (BufferedReader br = 
              new BufferedReader(new FileReader("data.txt"))){
            return p.process(br);
        }
}

传递Lambda

现在我们就可以通过传递不同的Lambda重用processFile方法,以不同方式处理文件。

处理一行:

代码语言:javascript
复制
String oneLine = processFile((BufferedReader br) -> br.readLine());

处理两行:

代码语言:javascript
复制
String twoLine = processFile((BufferedReader br) -> br.readLine() + br.readLine());

几种函数式接口

Java 8中常用的函数式接口有三个:Predicate,Consumer,Function。

Predicate

java.util.function.Predicate<T>接口定义了一个名叫test的抽象方法,它接受泛型T对象,并返回一个boolean。在需要表示一个涉及类型T的布尔表达式时,可以使用这个接口。比如,你可以定义一个接受String对象的Lambda表达式。

代码语言:javascript
复制
@FunctionalInterface
public interface Predicate<T> {
    boolean test(T t);
}

public static <T> List<T> filter(List<T> list, Predicate<T> p) { 
    List<T> results = new ArrayList<>(); 
    for(T s: list){ 
        if(p.test(s)){ 
            results.add(s); 
        } 
    } 
    return results; 
} 

Predicate<String> predicate = (String s) -> !s.isEmpty(); 
List<String> nonEmpty = filter(listOfStrings, predicate);

Consumer

java.util.function.Consumer<T>接口定义了一个名叫accept的抽象方法,它接受泛型T,没有返回值(void)。如果需要访问类型T的对象,并对其执行某些操作,可以使用这个接口。 比如定义一个forEach方法,接受一个Integer类型的列表,并对每个元素执行打印操作。

代码语言:javascript
复制
@FunctionalInterface
public interface Consumer<T> {
    void accept(T t);
}

public static <T> void forEach(List<T> list,Consumer<T> c) {
    for(T i: list) {
        c.accept(i);
    }
}

forEach(
    Arrays.asList(1,2,3,4,5),(Integer i) -> System.out.println(i)
);

Function

java.util.function.Function<T, R>接口定义了一个叫作apply的方法,它接受一个泛型T的对象,并返回一个泛型R的对象。如果需要定义一个Lambda,将输入的信息映射到输出,可以使用这个接口(比如提取苹果的重量,或把字符串映射为它的长度)。 比如,定义一个map方法,将一个String列表映射到包含每个String长度的Integer列表。

代码语言:javascript
复制
@FunctionalInterface 
public interface Function<T, R>{ 
    R apply(T t); 
} 

public static <T, R> List<R> map(List<T> list, Function<T, R> f) {   
    List<R> result = new ArrayList<>(); 
    for(T s: list){ 
        result.add(f.apply(s)); 
    } 
    return result; 
} 

// [6,3,6]
List<Integer> list = map(
        Arrays.asList("lambda","int","action"),
        (String s) -> s.length()
    );

Supplier

java.util.function.Supplier<T>接口定义了一个get的抽象方法,它没有参数,返回一个泛型T的对象,这类似于一个工厂方法。 比如返回一个Apple对象。

代码语言:javascript
复制
public interface Supplier<T> {
    T get();
}

public static <T> T getObject(Supplier<T> s) {
    return s.get();
}

Apple apple = getObject(() -> new Apple());
代码语言:javascript
复制
package com.zhangshangbiancheng.functional;

import java.util.function.*;

public class FunctionInterface {
    public static void main(String[] args) {
        //系统内部的函数式接口

        //Predicate<T>                 参数T  返回值boolean
            //IntPredicate              int->boolean
            //LongPredicate             long->boolean
            //DoublePredicate           double->boolean

        //Consumer<T>                    参数T  返回值void
            //IntConsumer                  int->boolean
            //LongConsumer                  long->void
            //DoubleConsumer                double->void


        //Function<T,R>                   参数T  返回值R   指定类型参数  指定类型返回值
            //IntFunction<R>                int->R
            //LongFunction<R>               long->R
            //DoubleFunction<R>             double->R
            //IntToLongFunction             int->long
            //LongToIntFunction             long->int
            //LongToDoubleFunction          long->double
            //DoubleToIntFunction           double->int
            //DoubleToLongFunction          double->long

        //Supplier<T>           参数无    返回值T


        //UnaryOperator<T>      参数T  返回值T
        //BinaryOperator<T>     参数T,T   返回值T       继承 BiFunction<T,U,R>
        //BiFunction<T,U,R>     参数T,U   返回值R
        //BiPredicate<T,U>      参数T,U    返回值boolean
        //BiConsumer<T,U>       参数T,U    返回值void



        //比较常用的函数式接口   Predicte<T>    Consumer<T>   Function<T,R>   Supplier<T>  其他只是补充

    }
}

在了解了Lambda表达式的和方法引用的用法之后,你就可以自己去尝试用Lambda表达式去简化一些代码了(你可以自己去练习一下)。不过用于传递Lambda表达式的Comparator、Function、Predicate等函数式接口提供了允许你进行复合的方法。这意味着你可以把多个简单的Lambda复合成复杂的表达式。有兴趣的童鞋可以自己去了解下,这里不再详细讲解。

项目地址:

代码语言:javascript
复制
https://github.com/Mazongdiulejinguzhou/Mazongdiulejinguzhou.github.io/tree/develop-Lambda-test
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-08-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 后端码匠 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么时候可以使用Lambda
  • Lambda表达式的具体使用
  • 如果我们想要从一个文件中读取一行所需的内容,可以定义这样的方法:
  • Lambda表达式的具体使用
  • 几种函数式接口
    • Predicate
      • Consumer
        • Function
          • Supplier
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档