Lambda表达式

简介: Lambda表达式

Lambdad表达式综合案例:

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

5.1、集合排序


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:


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、集合的遍历:


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、删除集合中元素:


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、线程相关:


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();
    }
    //
}

六、闭包


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;
        };
    }
}


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表达式是可以在函数式接口上使用的。函数式接口就是只定义一个抽象方法的接口。比如:


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表达式的具体使用

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


public static String processFile() throws IOException {
    try (BufferedReader br = 
            new BufferedReader(new FileReader("data.txt"))){
        return br.readLine();
    }
}


Lambda表达式的具体使用

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


public static String processFile() throws IOException {
    try (BufferedReader br = 
            new BufferedReader(new FileReader("data.txt"))){
        return br.readLine();
    }
}

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

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


public static String processFile(BufferedReaderProcessor p) throws Exception{
        try (BufferedReader br = 
              new BufferedReader(new FileReader("data.txt"))){
            return p.process(br);
        }
}


传递Lambda

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


处理一行:


String oneLine = processFile((BufferedReader br) -> br.readLine());

处理两行:


String twoLine = processFile((BufferedReader br) -> br.readLine() + br.readLine());


几种函数式接口

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

Predicate

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


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


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


@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接口定义了一个get的抽象方法,它没有参数,返回一个泛型T的对象,这类似于一个工厂方法。

比如返回一个Apple对象。


public interface Supplier<T> {
    T get();
}
public static <T> T getObject(Supplier<T> s) {
    return s.get();
}
Apple apple = getObject(() -> new Apple());


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复合成复杂的表达式。有兴趣的童鞋可以自己去了解下,这里不再详细讲解。项目地址:


https://github.com/Mazongdiulejinguzhou/Mazongdiulejinguzhou.github.io/tree/develop-Lambda-test

3bebb517885c4c4b3df7972724ace609.jpg

devlop-Lambda-test分支

目录
相关文章
|
4月前
|
算法 编译器 C++
C++一分钟之—Lambda表达式初探
【6月更文挑战第22天】C++的Lambda表达式是匿名函数的快捷方式,增强函数式编程能力。基本语法:`[capture](params) -&gt; ret_type { body }`。例如,简单的加法lambda:`[](int a, int b) { return a + b; }`。Lambda可用于捕获外部变量(值/引用),作为函数参数,如在`std::sort`中定制比较。注意点包括正确使用捕获列表、`mutable`关键字和返回类型推导。通过实践和理解这些概念,可以写出更简洁高效的C++代码。
46 13
|
4月前
|
C++
C++ lambda表达式
C++ lambda表达式
|
5月前
|
Java 编译器
Lambda表达式
Lambda表达式
27 0
|
编译器 C++
【C++】Lambda表达式的使用
【C++】Lambda表达式的使用
99 0
|
5月前
|
并行计算 Java 编译器
Lambda表达式超详解
Lambda表达式超详解
lambda表达式
lambda表达式是C++11引入的一种简洁的函数定义的方法。lambda表达式具有间接的语法和灵活的使用方式,让代码更加简洁和易读。特别是与function结合起来使得代码的编写更加灵活。本文将简单介绍lambda表达式的相关用法。
|
12月前
|
算法 编译器
C++11 lambda表达式(下)
C++11 lambda表达式(下)
83 2
|
存储 编译器 C++
c++ lambda表达式
c++ lambda表达式
80 0
|
Java
Lambda表达式的实际情况和应用
Lambda表达式是Java 8引入的一个重要特性,它提供了一种简洁而强大的方式来表示匿名函数。Lambda表达式可以用于各种情况和应用,包括但不限于以下几个方面:
70 0
|
Java
浅谈lambda表达式
浅谈lambda表达式
62 0