java8 新特性-lambda 表达式

本文深入介绍了Java 8的Lambda表达式,它是一种行为参数化的方式,简化了代码,提高了可读性。通过@FunctionalInterface标记的函数式接口,Lambda表达式可以作为参数传递,实现多变的需求。文章详细讲解了Lambda的结构、应用场景,如接口参数化,并展示了如何使用Comparator、Function和Predicate等内置函数式接口。此外,还提供了过滤、消费和转换等实际案例,进一步解释了Lambda在实际编程中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是lambda ? 解决什么问题?

要知道lambda 表达式,首先要先了解函数式接口

函数式接口,就是一个接口只提供一个方法(但可以有多个默认方法),并可以再接口上方用@FunctionalInterface 来标记。如下:

@FunctionalInterface
public interface Function<T, R> {
    R apply(T t);
}

这里的接口,我们能明确它的入参类型,出参类型,处理逻辑由具体的实现类来实现。所以我们所关注的其实只有方法实现本生。lambda 是指是匿名内部类,省略了一大堆不必要的元素,只保留了入参出参处理逻辑。具体结构参考 lambda 表达式的结构

lambda 是行为参数化 的一种重要表现方式。

解决问题:针对多变的需求,接口作为参数传递是比较好的解耦方式;极大的简化代码。

lambda 表达式的结构

(x,y)-> x + y  // (parameters) -> expression  或 (parameters) -> { statements; }

parameters:(x,y) 此部分是 参数列表

参数2:-> 箭头

参数3:lambda 表达式主体,可以是简单的一个表达式,也可以是复杂的多个表达式。多个表达式要带 {};

lambda 应用场景

接口参数化,我们来看一个 java 8 in action 中的例子。

public static String processFile() throws IOException{
	try(BufferedReader br = new BufferedReader(new FileReader("data.txt"))){
		return br.readLine();
	}
}
//定义函数式接口
@FunctionalInterface
public interface BufferedReaderProcessor{
    String process(BufferedReader b) throws IOException;
}
//入参接口
public static String processFile(BufferedReaderProcessor p)  throws IOException{
    try(BufferedReader br = new BufferedReader(new FileReader("data.txt"))){
        return p.process(br);
    }
}
//方法调用,行为参数
String online = processFile((BufferedReader br)->br.readLine());

JDK 自带的几个常用函数式接口,在后面的 stream 等很多地方都有使用。

//有返回值
@FunctionalInterface
public interface Function<T, R> {
    R apply(T t);
}
//无返回值
@FunctionalInterface
public interface Consumer<T> {
    void accept(T t);
}
//返回 boolean 类型
@FunctionalInterface
public interface Predicate<T> {
    boolean test(T t);
}

除此之后,JDK 中还定义了很多这三类的变形函数式接口。当然,我们自己也可以定义自己的函数式接口。

类型检查、类型推断与限制

类型检查,根据接口定义时指定泛型进行检查。

类型推断,根据接口定义指定泛型进行推断。如:

public class Apple {
        private String color;
        private int weight;
        //getter,setter
}
//接口定义如下
@FunctionalInterface
public interface Comparator<T> {
 int compare(T o1, T o2);
 }
//lambda 表达式。此时泛型T 指代的是 Apple
Comparator<Apple> a = (a, b) -> a.getColor().compareTo(b.getColor());

复合lambda表达式使用

所谓复合,即通过接口提供多个default 方法,进行多重操作。Comparator (比较器复合)、 Function(函数复合) 和 Predicate (谓词复合)都有各自的复合操作。

例如,Comparator :sort, reversed, thenComparing

//Comparator 按重量递减排序
inventory.sort(comparing(Apple::getWeight).reversed()); 
//Comparator 比较链
inventory.sort(comparing(Apple::getWeight) 
         .reversed()  
         .thenComparing(Apple::getCountry)); 

Predicate:

//Predicate negate
Predicate<Apple> notRedApple = redApple.negate();
//Predicate and
Predicate<Apple> redAndHeavyApple = 
    redApple.and(a -> a.getWeight() > 150);    
//Predicate  and 和 or
Predicate<Apple> redAndHeavyAppleOrGreen = 
    redApple.and(a -> a.getWeight() > 150) 
            .or(a -> "green".equals(a.getColor())); 

Function: andThen 和 compose 表示 f(g(x))

Function<Integer, Integer> f = x -> x + 1; 
Function<Integer, Integer> g = x -> x * 2; 
Function<Integer, Integer> h = f.andThen(g); 
int result = h.apply(1);    
//或者 注意f 与 g 的先后顺序
Function<Integer, Integer> f = x -> x + 1; 
Function<Integer, Integer> g = x -> x * 2; 
Function<Integer, Integer> h = f.compose(g);    
int result = h.apply(1); 

常见案例

说明:案例中的所有实体 Apple 如下:

@Data
public class Apple {
    private String color;
    private int weight;
 }

Predicate:

public class Predicate {

    public static List<Apple> filter(List<Apple> apples, Predicate<Apple> predicate) {

        List<Apple> result = new ArrayList<>();
        for (Apple apple : apples) {
            if (predicate.test(apple))
                result.add(apple);
        }
        return result;
    }

    public static List<Apple> filter2(List<Apple> apples, IntPredicate intPredicate) {
        List<Apple> result = new ArrayList<>();
        for (Apple apple : apples) {
            if (intPredicate.test(apple.getWeight()))
                result.add(apple);
        }
        return result;
    }

    public static List<Apple> colorAndWeightFilter(List<Apple> apples, BiPredicate<String, Integer> biPredicate) {
        List<Apple> result = new ArrayList<>();
        for (Apple apple : apples) {
            if (biPredicate.test(apple.getColor(), apple.getWeight()))
                result.add(apple);
        }
        return result;
    }
    public static void main(String[] args) {
        List<Apple> apples = Arrays.asList(new Apple("a", 50), new Apple("b", 60));
        List<Apple> a1 = filter(apples, (a) -> a.getColor().equals("a"));
        System.out.println(a1);

        //使用 intpredicate
        List<Apple> apples1 = filter2(apples, a -> a > 50);
        System.out.println(apples1);

        //使用 bipredicate 两个参数
        List<Apple> apples2 = colorAndWeightFilter(apples, (a, b) -> a.equals("a") && b == 50);
        System.out.println(apples2);

        Predicate<Apple> com = a -> a.getColor().equals("a");
        com.and(a -> a.getWeight() > 10).or(a -> a.getColor().equals("b")).test(new Apple());
    }
}

Consumer:

public class Consumer {
    public static void simpleConsumer(List<Apple> apples, Consumer<Apple> consumer) {
        for (Apple apple : apples) {
            consumer.accept(apple);
        }
    }

    public static void biSimpleConsumer(List<Apple> apples, String color, BiConsumer<Apple, String> biConsumer) {
        for (Apple apple : apples) {
            biConsumer.accept(apple,color);
        }
    }

    public static void main(String[] args) {
        List<Apple> apples = Arrays.asList(new Apple("a", 50), new Apple("b", 60));
        //简单的consumer
        simpleConsumer(apples, System.out::println);

        //biconsumer
        biSimpleConsumer(apples,"a",(a,b)->{
            boolean f = a.getColor().equals(b);
            if (f) {
                System.out.println(a);
            }
        });
    }
}

Function:

public class Function {
    public static Apple bifunction(String color, Integer weight, BiFunction<String, Integer, Apple> biFunction) {

        return new Apple(color, weight);
    }

    public static void main(String[] args) {
        //简单 function
        Function<String, Integer> flambda = String::length;

        //简单bifunction
        Apple a = bifunction("a", 61, Apple::new);
        System.out.println(a);

        int i = Integer.parseInt("123");
        Function<String,Integer> fun = Integer::parseInt;
        Integer apply = fun.apply("123");
        System.out.println(apply);

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值