Java 8-函数式接口

目录

一、概述

二、 函数式接口作为方法的参数

三、函数式接口作为方法的返回值

四、 常用的函数式接口

简单总结

简单示例

4.1 Consumer接口

简单案例

自我练习

实际应用场景

多线程处理

4.2 Supplier接口

简单案例

自我练习

实际应用场景

配置管理

4.3 Function接口

简单案例

自我练习

实际应用场景

数据转换器

数据映射

4.4 Predicate接口

简单案例

自我练习

实际应用场景

权限验证

4.5 综合应用案例

五、Lambda 应用

1.Consumer (消费型接口)

2.Supplier (供给型接口)

3..Function (函数型接口)

4..Predicate (断言型接口)


一、概述

定义:有且仅有一个抽象方法的接口

  • Java中函数式编程体现:Lambda表达式

  • 函数式接口就是可以适用于Lambda使用的接口

    • 只有确保接口中仅有一个抽象方法,Java中的Lambda才能顺利地进行推导

如何检测一个接口是不是函数式接口?

  • @Functionallnterface

  • 放在 接口定义的上方:如果接口是函数式接口,编译通过;如果不是,编译失败

注意:

我们自己定义函数式接口的时候,@Functionallnterface是可以选的,就算我们不写这个注解,只要保证满足函数式接口定义的条件,也照样是函数式接口。但是,建议加上该注解,虽然这不是强制性的,但使用它可以避免无意中添加额外的方法,从而破坏函数式接口的特性。

核心概念

  • 函数式接口:具有且仅有一个抽象方法的接口。

  • Lambda表达式:一种匿名函数,可以用来替代只有单一方法的类的实例化。

  • 方法引用:如果Lambda表达式只是简单地引用已有方法,那么可以用方法引用代替Lambda表达式。

二、 函数式接口作为方法的参数

需求

  • 定义一个类(RunnableDemo),在类中提供两个方法

    • 一个方法是:startThread(Runnable r) 方法参数Runnabler是一个函数式接口

    • 一个方法是主方法,在主方法中调用startThread方法

如果方法的参数是一个函数式接口,我们可以用Lambda表达式作为参数传递

startThread(()->System.out.println(Thread.currentThread().getName()+“线程启动了”));
public class RunnableDemo {public static void main(String[] args) {// Lambda表达式作为参数传递 startThread(()-> System.out.println(Thread.currentThread().getName()+"线程启动了"));}
​private static void startThread(Runnable r){new Thread(r).start();}
}

三、函数式接口作为方法的返回值

需求

  • 定义一个类(ComparatorDemo),在类中提供两个方法

    • 一个方法是:Comparator< String > getComparator() 方法返回值Comparator是一个函数式接口

    • 一个方法是主方法,在主方法中调用getComparator方法

如果一个方法的返回值是一个函数式接口,我们可以把一个Lambda表达式作为结果返回

private static Comparator<String> getComparator() {// 定义了一个接受两个参数 s1 和 s2 的函数,这两个参数都是字符串类型。计算 s1 的长度减去 s2 的长度,并返回结果return (s1, s2) -> s1.length() - s2.length();
}


package com.geeksss.excel.model;
​
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
​
/*** ComparatorDemo 使用自定义比较器对字符串列表进行排序。*/
public class ComparatorDemo {/*** 主函数执行字符串列表的排序操作。* @param args 命令行参数,未使用。*/public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("cccc");list.add("aa");list.add("b");list.add("ddd");System.out.println("排序前" + list);// 使用自定义比较器对列表进行排序。Collections.sort(list, getComparator());System.out.println("排序后" + list);}/*** 使用Lambda表达式创建并返回Comparator实例* 获取一个比较器实例,该比较器按字符串长度进行排序。**  Lambda表达式: (s1, s2) -> s1.length() - s2.length()*  这个表达式定义了一个比较规则,根据字符串的长度进行比较*  当s1.length() > s2.length(),返回正值,表示s1在排序中应该位于s2之后,s1比s2长*  当s1.length() < s2.length(),返回负值,表示s1在排序中应该位于s2之前,s1比s2短*  当s1.length() == s2.length(),返回0,表示两个字符串长度相等,保持原顺序,s1与s2一样长**  方法的返回值是一个函数式接口,把一个Lambda表达式作为返回结果* @return 返回一个 Comparator 实例,用于按照字符串长度进行排序。*/private static Comparator<String> getComparator() {// 使用 Lambda 表达式定义比较逻辑:按字符串长度进行比较。// 使用匿名内部类实现
//        return new Comparator<String>() {
//            @Override
//            public int compare(String s1, String s2) {
//                return s1.length()-s2.length();
//            }
//        };// Lambda 表达式写法,等效于上述匿名内部类实现。return (s1, s2) -> s1.length() - s2.length();}
​
​
}
​
 

排序前[cccc, aaaa, b, ddd] 排序后[b, ddd, cccc, aaaa]

四、 常用的函数式接口

Java 8在java.util.function包下预定义了大量的函数式接口供我们使用,重点学习下面4个接口

简单总结
  • Consumer<T>:接收一个参数,但没有返回值。

    • 常用于遍历数据结构,执行副作用操作,如打印或更新状态

  • Supplier<T>:不接收参数,返回一个结果。

    • 可以用于创建延迟初始化的对象,或获取数据源的值

  • Function<T, R>:接收一个参数并返回一个结果。

    • 可以用于数据转换或映射

  • Predicate<T>:接收一个参数并返回一个布尔值。

    • 通常用于数据过滤

简单示例
import java.util.function.*;
​
public class FunctionalInterfaceExample {
​public static void main(String[] args) {// Consumer 示例Consumer<String> printUpperCase = System.out::println;printUpperCase.accept("HELLO"); // 输出 HELLO// Supplier 示例Supplier<Double> randomSupplier = Math::random;System.out.println(randomSupplier.get()); // 输出一个随机数// Function 示例Function<String, Integer> stringToInt = Integer::parseInt;System.out.println(stringToInt.apply("123")); // 输出 123// Predicate 示例Predicate<Integer> isEven = x -> x % 2 == 0;System.out.println(isEven.test(4)); // 输出 true}
}
​
4.1 Consumer接口

Consumer是一个消费型接口,它接受一个参数但不返回任何值。它常用于对集合中的元素执行某种操作,如打印或修改数据。

Consumer< T >:包含两个方法

  • void accept(T t):对给定的参数执行此操作

  • default Consumer < T > andThen(Consumer after):返回一个组合的Consumer,依次执行此操作,然后执行after操作

  • Consumer< T >接口也被称为消费型接口,它消费的数据类型由泛型指定

简单案例
package com.geeksss.excel.model;
​
import java.util.function.Consumer;
​
/*** 消费者示例类,使用Consumer接口处理字符串。*/
public class ConsumerDemo {public static void main(String[] args) {// 单个消费者处理字符串operatorString("张三", (s) -> System.out.println(s));// 两个消费者依次处理字符串operatorString("张三", (s) -> System.out.println(s), (s) -> System.out.println(new StringBuilder(s).reverse().toString()));}/*** 接受一个字符串并应用一个消费者。* @param name 要处理的字符串* @param con 字符串的消费者*/// 定义一个方法,消费一个字符串数据private static void operatorString(String name, Consumer<String> con) {con.accept(name);}/*** 接受一个字符串并依次应用两个消费者。* @param name 要处理的字符串* @param con1 第一个字符串消费者* @param con2 第二个字符串消费者*/// 定义一个方法,用不同的方式消费同一个字符串两次private static void operatorString(String name, Consumer<String> con1, Consumer<String> con2) {// 通过andThen方法将两个消费者串联起来,形成一个消费链// 返回一个组合的Consumercon1.andThen(con2).accept(name);}// 张三// 张三// 三张
}
自我练习
  • String[] strArray = {“张三,30”, “李四,21”, “王五,18”};

  • 字符串数组中有多条信息,按照格式:

    • 把打印姓名的动作,作为第一个Consumer接口的Lambda实例

    • 把打印年龄的动作,作为第二个Consumer接口的Lambda实例

    • 将两个Consumer接口按照顺序组合到一起使用

package com.geeksss.excel.model;
​
import java.util.Arrays;
import java.util.function.Consumer;
​
/*** @author zhumq* @date 2024/7/30 22:27*/
public class ConsumerTest {public static void main(String[] args) {String[] strArray = {"张三,30", "李四,21", "王五,18"};// 使用operatorString方法处理字符串数组,分别输出原字符串和分割后的数组operatorString(strArray, (s) -> System.out.println(s), (s) -> System.out.println(Arrays.toString(s.split(","))));}/*** 对字符串数组中的每个元素应用两个消费者操作:首先执行第一个消费者,然后执行第二个消费者。** @param strArray 字符串数组* @param con1     第一个字符串消费者* @param con2     第二个字符串消费者*/public static void operatorString(String[] strArray, Consumer<String> con1, Consumer<String> con2) {for (String str : strArray) {// 通过andThen方法将两个消费者串联起来,形成一个消费链con1.andThen(con2).accept(str);}}// 张三,30// [张三, 30]// 李四,21// [李四, 21]// 王五,18// [王五, 18]
}
实际应用场景
多线程处理

Consumer接口在多线程环境中非常有用,可以用于并行处理数据集中的每个元素,例如在异步任务中处理数据。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Consumer;
​
public class MultiThreadedProcessing {public static void main(String[] args) {ExecutorService executor = Executors.newFixedThreadPool(4);Consumer<String> processTask = task -> {System.out.println("Processing task '" + task + "' on thread " + Thread.currentThread().getName());// 这里可以是任务的具体处理逻辑};
​for (int i = 0; i < 10; i++) {String task = "Task-" + i;executor.submit(() -> processTask.accept(task));}
​executor.shutdown();}
}
​

4.2 Supplier<T>接口

Supplier< T >:包含一个无参的方法

  • T get():获得结果

  • 该方法不需要参数,他会按照某种实现逻辑返回一个数据(由Lambda表达式实现)

  • Supplier< T >接口也被称为生产型接口,如果我们指定了接口的泛型是什么类型,那么接口中的get方法就会产生什么类型的数据供我们使用

简单案例
import java.util.function.Supplier;public class SupplierDemo {public static void main(String[] args) {String s = getString(()->"张三");int i = getInteger(()->18);System.out.println(s+","+i);}//定义一个方法,返回一个字符串数据private static String getString(Supplier<String> sup){return sup.get();}//定义一个方法,返回一个整数数据private static Integer getInteger(Supplier<Integer> sup){return sup.get();}
}
自我练习
  • 定义一个类(SupplierTest),在类中提供两个方法

    • 一个方法是:int getMax(Supplier< Integer > sup) 用于返回一个int数组中的最大值

    • 一个方法是主方法,在主方法中调用getMax方法

package com.geeksss.excel.model;import java.util.function.Supplier;
/*** SupplierTest 使用 Supplier 接口来获取一个值*/
public class SupplierTest {public static void main(String[] args) {// 初始化一个整型数组int[] i = {3,75,32,76,98,42};// 使用 getMax 方法来获取数组中的最大值,传递一个 Supplier 实现来计算最大值int maxValue = getMax(()->{int max = i[0];// 遍历数组找到最大值for (int j = 1; j < i.length; j++) {if(i[j]>max){max = i[j];}}return max;});System.out.println(maxValue);}/*** 使用 Supplier 获取一个值。* @param sup 提供值的 Supplier 实例* @return 由 Supplier 提供的值*/private static Integer getMax(Supplier<Integer> sup){return sup.get();}
}
实际应用场景
配置管理

Supplier可以用于配置管理,例如延迟加载配置项,确保配置在首次请求时才被读取,从而节省资源。

import java.util.function.Supplier;public class ConfigurationManager {private Supplier<String> configSupplier;public ConfigurationManager(Supplier<String> configSupplier) {this.configSupplier = configSupplier;}public String getConfig() {return configSupplier.get();}
}// 使用示例
public class ConfigLoader {public static void main(String[] args) {ConfigurationManager manager = new ConfigurationManager(() -> {// 模拟从文件或网络加载配置return "Loaded configuration";});System.out.println(manager.getConfig());}
}

4.3 Function接口

Runction<T,R>:常用的两个方法

  • R apply(T t):将此函数应用于给定的参数

  • default< V >:Function andThen(Function after):返回一个组合函数,首先将该函数应用于输入,然后将after函数应用于结果

  • Function<T,R>:接口通常用于对参数进行处理转换,然后返回一个新值(处理逻辑由Lambda表达式实现)

简单案例
import java.util.function.Function;public class FunctionExample {public static void main(String[] args) {// 创建一个 Function 对象,它接受一个 String 类型的参数并返回一个 Integer 类型的结果, 引用 String::length,是 Lambda 表达式的简洁版Function<String, Integer> stringLengthFunction = String::length;// 使用 apply 方法调用 Function 对象,传入一个具体的 String 参数。int length = stringLengthFunction.apply("Hello, World!");System.out.println("The length of the string is: " + length);}
}
自我练习
package com.dev.springBootDemo;import java.util.function.Function;/*** FunctionTest 不同类型的转换函数的使用*/
public class FunctionTest {public static void main(String[] args) {// 字符串转整数并打印convert("18", s -> Integer.parseInt(s));// 整数加法运算后转字符串并打印convert(20, integer -> String.valueOf(integer + 18));// 字符串转整数,整数加法运算后转字符串并打印convert("245", s -> Integer.parseInt(s), integer -> String.valueOf(integer + 18));}/*** 将字符串转换为整数并打印。* @param s 要转换的字符串* @param fun 字符串到整数的转换函数*/// 定义一个方法,把一个字符串转换成int类型,在控制台输出private static void convert(String s, Function<String, Integer> fun) {int i = fun.apply(s);System.out.println(i);}/*** 将整数进行运算后转换为字符串并打印。* @param i 要转换的整数* @param fun 整数到字符串的转换函数*/// 定义一个方法,把int类型数据加上一个整数之后,转换为字符串在控制台输出private static void convert(int i, Function<Integer, String> fun) {String s = fun.apply(i);System.out.println(s);}/*** 将字符串转换为整数,进行运算后再转换为字符串并打印。* @param s 要转换的字符串* @param fun1 字符串到整数的转换函数* @param fun2 整数到字符串的转换函数*/// 定义一个方法,把一个字符串转换int类型,把int类型的数据加上一个整数后,转换成字符串在控制台输出private static void convert(String s, Function<String, Integer> fun1, Function<Integer, String> fun2) {String s1 = fun2.apply(fun1.apply(s));System.out.println(s1);}
}

实际应用场景
数据转换器

假设正在开发一个系统,需要处理来自不同来源的数据,这些数据可能以不同的格式存储。可以使用 Function 接口来创建转换器,将这些数据转换成统一的格式。例如,可能有一个函数将 JSON 字符串转换为对象,另一个函数将 XML 转换为对象,等等。这样,可以在系统中重用这些,提高代码的可读性和可维护性。

package com.dev.springBootDemo;import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.google.gson.Gson;import java.util.function.Function;
/*** 数据转换器类,用于根据提供的转换函数将原始数据转换为特定类型。*/
public class DataConverter {/*** 使用提供的转换函数将原始数据转换为指定类型。** @param rawData 原始数据,以字符串形式表示。* @param converter 转换函数,用于将原始数据字符串转换为目标类型T。* @param <T> 目标数据类型。* @return 转换后的数据对象。*/// 定义一个通用的转换函数,它接受一个 String 类型的原始数据和一个 Function 对象,// 该 Function 对象负责将原始数据转换为目标类型 T。public static <T> T convertData(String rawData, Function<String, T> converter) {return converter.apply(rawData);}public static void main(String[] args) {// 假设我们有 JSON 和 XML 数据String jsonData = "{\"name\":\"John\", \"age\":30}";String xmlData = "<person><name>John</name><age>30</age></person>";// JSON 转换器Function<String, Person> jsonConverter = s -> new Gson().fromJson(s, Person.class);// XML 转换器Function<String, Person> xmlConverter = s -> new XmlMapper().readValue(s, Person.class);// 使用转换函数将JSON数据转换为Person对象Person personFromJson = convertData(jsonData, jsonConverter);// 使用转换函数将XML数据转换为Person对象Person personFromXml = convertData(xmlData, xmlConverter);System.out.println(personFromJson);System.out.println(personFromXml);}
}
数据映射

Function接口在数据映射和转换中扮演重要角色,例如将一种数据类型转换为另一种数据类型。

import java.util.function.Function;public class DataMapper {public static void main(String[] args) {Function<String, Integer> parseInteger = Integer::parseInt;String input = "123";Integer output = parseInteger.apply(input);System.out.println("Parsed integer: " + output);}
}

4.4 Predicate接口

常用于

Predicate< T >:常用的四个方法

  • boolean test(T t):对给定的参数进行判断,返回一个布尔值(判断逻辑由Lambda表达式实现)

  • default Predicate< T > negate():返回一个逻辑的否定,对应逻辑非

  • default Predicate< T > and():返回一个组合判断,对应短路与

  • default Predicate< T > or():返回一个组合判断,对应短路或

  • isEqual():测试两个参数是否相等

  • Predicate< T >:接口通常用于判断参数是否满足指定的条件

test(T t) 、negate()

简单案例
package com.dev.springBootDemo;import java.util.function.Predicate;public class PredicateDemo {public static void main(String[] args) {// 检查字符串是否等于"张三"boolean string = chenkString("张三", s -> s.equals("张三"));System.out.println(string);// 检查字符串长度是否大于8且小于18boolean hello = chenkString("hello", s -> s.length() > 8, s -> s.length() < 18);System.out.println(hello); // true}/*** 使用单个谓词检查字符串是否满足条件。** @param s 要检查的字符串* @param pre 字符串检查谓词* @return 如果字符串满足谓词条件,则返回true;否则返回false。*/// 判定给定的字符串是否满足要求// private static boolean chenkString(String s, Predicate<String> pre){//     return pre.test(s); // true// }/*** 使用单个谓词的否定检查字符串是否不满足条件。** @param s 要检查的字符串* @param pre 字符串检查谓词* @return 如果字符串不满足谓词条件,则返回true;否则返回false。*/private static boolean chenkString(String s, Predicate<String> pre){return pre.negate().test(s); // false}/*** 使用两个谓词的逻辑与检查字符串是否同时满足两个条件。** @param s 要检查的字符串* @param pre 第一个字符串检查谓词* @param pre1 第二个字符串检查谓词* @return 如果字符串同时满足两个谓词条件,则返回true;否则返回false。*/// private static boolean chenkString(String s, Predicate<String> pre, Predicate<String> pre1){//     return pre.and(pre1).test(s); // false// }java/*** 使用两个谓词的逻辑或检查字符串是否满足其中一个条件。** @param s 要检查的字符串* @param pre 第一个字符串检查谓词* @param pre1 第二个字符串检查谓词* @return 如果字符串满足两个谓词中的任何一个,则返回true;否则返回false。*/private static boolean chenkString(String s, Predicate<String> pre, Predicate<String> pre1){return pre.or(pre1).test(s); // true}
}
自我练习
  • String[] strArray = {“张三,30”, “李四,21”, “王五,18”};

  • 字符串数组中由多条信息,请通过Predicate接口的拼装将符合要求的字符串筛选到集合Arraylist中,并遍历ArrayList集合

  • 同时满足如下:姓名长度大于1,年龄大于20

  • 分析

    • 有两个判断条件,所以需要使用两个Predicate接口,对条件进行判断

    • 必须同时满足两个条件,所以可以使用and方法连接两个判断条件

package com.dev.springBootDemo;import java.util.ArrayList;
import java.util.function.Predicate;/*** 消费者测试类,使用自定义过滤函数筛选数据。*/
public class PredicateTest {public static void main(String[] args) {// 初始化一个字符串数组,包含姓名和年龄信息。String[] strArray = {"张三,30", "李四,21", "王五,18"};// 使用myFilter方法筛选出姓名长度大于1且年龄大于20的人名。ArrayList<String> arrayList = myFilter(strArray,s -> s.split(",")[0].length() > 1,s -> Integer.parseInt(s.split(",")[1]) > 20);// 遍历并打印筛选结果。for (String array : arrayList) {System.out.println(array);}}/*** 自定义过滤方法,根据提供的两个Predicate条件对字符串数组进行筛选。* * @param strArray 输入的字符串数组,每个元素包含一个姓名和一个数字。* @param pre1 第一个过滤条件的Predicate。* @param pre2 第二个过滤条件的Predicate。* @return 符合所有条件的字符串集合。*/// 通过Predicate接口的拼装将符合要求的字符串筛选到集合Arraylist中private static ArrayList<String> myFilter(String[] strArray, Predicate<String> pre1, Predicate<String> pre2) {// 初始化一个ArrayList用于存储筛选结果。ArrayList<String> array = new ArrayList<>();// 遍历输入数组。for (String str : strArray) {// 如果字符串同时满足pre1和pre2两个条件,则添加到结果集合中。if (pre1.and(pre2).test(str)) {array.add(str);}}// 返回筛选结果。return array;}
}
实际应用场景
权限验证

Predicate在权限验证和安全检查中非常有用,例如检查用户是否有访问特定资源的权限。import java.util.function.Predicate;public class PermissionChecker {public static void main(String[] args) {Predicate<String> hasPermission = role -> role.equals("admin");String userRole = "admin";boolean canAccess = hasPermission.test(userRole);System.out.println("Can access: " + canAccess);}
}
 
4.5 综合应用案例

使用这些函数式接口来处理一个员工列表,并执行诸如筛选、转换和输出等操作。

假设有一个Employee类,它有name和age属性,想要从员工列表中找出所有年龄超过30岁的员工的名字,并将这些名字转换为大写形式,最后打印出来。

  • Supplier用于初始化一个空的List<String>,这是结果容器。

  • Predicate用于筛选出年龄大于30岁的员工。

  • Function用于将员工对象转换为大写形式的名字。

  • Consumer用于将转换后的大写名字添加到结果列表中。

首先,定义Employee类:

package com.dev.springBootDemo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;/*** @author zhumq* @date 2024/7/30 23:25*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Employee {private String name;private int age;
}

接下来,使用Predicate, Function, Consumer和Supplier来解决问题:

package com.dev.springBootDemo;import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;public class EmployeeProcessor {public static void main(String[] args) {// 创建员工列表List<Employee> employees = new ArrayList<>();employees.add(new Employee("张三", 35));employees.add(new Employee("李四", 28));employees.add(new Employee("王五", 42));employees.add(new Employee("陈六", 31));// 使用Supplier初始化一个空的List<String>,用于存放结果Supplier<List<String>> supplier = ArrayList::new;// 使用Predicate过滤年龄大于30岁的员工Predicate<Employee> predicate = employee -> employee.getAge() > 30;// 使用Function将Employee转换为其大写名字Function<Employee, String> function = employee -> employee.getName().toUpperCase();// 使用Consumer将转换后的名字添加到List中Consumer<String> consumer = supplier.get()::add;// 执行操作List<String> filteredNames = employees.stream().filter(predicate).map(function).collect(Collectors.toList());// 使用Consumer打印结果filteredNames.forEach(System.out::println);}
}

张三 王五 陈六

五、Lambda 应用

1.Consumer (消费型接口)

Consumer用于消费一个对象,常用于Stream的forEach()方法。

import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;public class ConsumerExample {public static void main(String[] args) {List<String> names = Arrays.asList("Alice", "Bob", "Charlie");// 使用Consumer打印每个名字names.forEach(System.out::println);}
}
2.Supplier (供给型接口)

Supplier用于生成一个对象,常用于初始化数据源或延迟加载。

import java.util.function.Supplier;public class SupplierExample {public static void main(String[] args) {Supplier<String> helloWorld = () -> "Hello, World!";// 使用Supplier获取结果System.out.println(helloWorld.get());}
}
3..Function (函数型接口)

Function用于将一个类型的数据转换为另一个类型的数据,常用于Stream的map()方法。

import java.util.Arrays;
import java.util.List;
import java.util.function.Function;public class FunctionExample {public static void main(String[] args) {List<String> words = Arrays.asList("one", "two", "three");// 使用Function将字符串转换为大写List<String> upperCaseWords = words.stream().map(String::toUpperCase).toList();System.out.println("Upper case words: " + upperCaseWords);}
}

4..Predicate (断言型接口)

Predicate用于判断一个对象是否满足某个条件,常用于Stream的filter()方法。

import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;public class PredicateExample {public static void main(String[] args) {List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);// 使用Predicate过滤出偶数List<Integer> evenNumbers = numbers.stream().filter(n -> n % 2 == 0).toList();System.out.println("Even numbers: " + evenNumbers);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3279996.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

MindIE Service服务化集成部署通义千问Qwen模型

一、昇腾开发者平台申请镜像 登录Ascend官网昇腾社区-官网丨昇腾万里 让智能无所不及 二、登录并下载mindie镜像 #登录docker login -u XXX#密码XXX#下载镜像docker pull XXX 三、下载Qwen的镜像 使用wget命令下载Qwen1.5-0.5B-Chat镜像&#xff0c;放在/mnt/Qwen/Qwen1.5-…

将项目部署到docker容器上

通过docker部署前后端项目 前置条件 需要在docker中拉去jdk镜像、nginx镜像 docker pull openjdk:17 #拉取openjdk17镜像 docker pull nginx #拉取nginx镜像部署后端 1.打包后端项目 点击maven插件下面的Lifecycle的package 对后端项目进行打包 等待打包完成即可 2.将打…

源码搭建国内微短剧系统上架(微信抖音)所需资质全面解析

随着短视频和微短剧市场的持续升温&#xff0c;越来越多的企业和个人开始关注并尝试进入这一领域。微短剧以其短小精悍、内容丰富的特点&#xff0c;吸引了大量用户的关注。对于想要搭建并运营自己的微短剧系统的创业者来说&#xff0c;选择合适的平台以及准备必要的资质成为了…

Linux下文件编译器-GCC/G++

前言 本文介绍了c/c的编译过程以及gcc/g的时使用 一.c/c翻译的本质&#xff1a;将高级语言翻译成二进制 1&#xff09;程序翻译过程&#xff1a; &#xff08;1&#xff09;预处理&#xff08;头文件展开、宏替换、去注释、条件编译&#xff09;还是C语言代码 ​ …

ad9361 CTRL_OUT0~7对应能读到的状态

ad9361 CTRL_OUT对应能读到的状态

新手小白如何投放知乎信息流广告推广?

随着越来越多的企业开始寻求更有效的方式来触达目标客户&#xff0c;知乎作为一个集知识分享、社交互动于一体的平台&#xff0c;已经成为众多品牌青睐的广告投放渠道之一。特别是知乎的信息流广告&#xff0c;因其高度融合的内容形式和精准的目标用户定向&#xff0c;成为了品…

《计算机网络》(第8版)第五章 运输层 复习笔记

第五章 运输层 一、运输层协议概述 1 运输层的功能 从通信和信息处理角度讲&#xff0c;传输层向应用层提供服务&#xff0c;是面向通信的最高层&#xff0c;也是面 向用户功能的最底层&#xff0c;它的主要功能有&#xff1a; &#xff08;1&#xff09;提供用户进程之间的逻…

HTML基础1-文本级元素

HTML 简介 什么是 HTML&#xff1f; HTML (HyperText Markup Language) 是一种用于创建网页的标准标记语言。它通过使用一系列预定义的元素来描述文档的结构和外观&#xff0c; 您可以使用 HTML 来建立自己的 WEB 站点。 HTML 的作用 HTML 用于定义网页的结构&#xff0c;…

Openwrt接UVC摄像头丢帧分析

Openwrt接UVC摄像头&#xff0c;使用mjpg-streamer&#xff0c;此处默认已经移植成功。这里以Skylab的SKW99为例进行说明&#xff0c;SKW99为高通QCA9531的方案&#xff0c;CPU的频率为650MHz。最近在应用过程中&#xff0c;需求完成后&#xff0c;发现视频码流下降了&#xff…

入门 PyQt6 看过来(案例)16~ 竖状菜单

本文依照上一篇文章进行简单的拓展&#xff0c;做一个竖状的堆栈菜单。效果如下&#xff1a; ​ 首先我们先进行分析以&#xff0c;页面左侧是菜单栏&#xff0c;按照堆栈式列表展示&#xff0c;包含基本信息和编程语言&#xff08;仔细的你是否发现路老师文字写错了&#xff1…

【数据结构】链式二叉树的实现和思路分析及二叉树OJ

【数据结构】链式二叉树的实现和思路分析及二叉树OJ &#x1f525;个人主页&#xff1a;大白的编程日记 &#x1f525;专栏&#xff1a;数据结构 文章目录 【数据结构】链式二叉树的实现和思路分析及二叉树OJ前言一.链式二叉树的定义及结构二.链式二叉树的遍历2.1前序遍历2.2中…

汇昌联信数字做拼多多运营实力强吗?

拼多多作为中国领先的电商平台之一&#xff0c;其运营实力一直是业界关注的焦点。汇昌联信数字公司作为一家专注于电商运营的企业&#xff0c;其在拼多多平台上的表现如何&#xff0c;是否具备强大的运营能力&#xff0c;是本篇文章探讨的主题。 一、答案是肯定的&#xff0c;汇…

C++高性能通信:图形简述高性能中间件Iceoryx

文章目录 1. 概述2. 支持一个发布者多个订阅者2.2 Iceoryx为何不支持多个发布者发布到同一个主题 3. Iceoryx的架构和数据传输示意图3.1 发布者与订阅者的通信机制3.2 零拷贝共享内存通信机制 4. 使用事件驱动机制4.1 WaitSet机制4.2 Listener机制 5. 已知限制6. 参考 1. 概述 …

Python .whl 独立安装和全部依赖安装命令

以安装 Flask 为例&#xff1a; 1. 独立安装 pip install whl_files/Flask-1.1.2-py2.py3-none-any.whl 2. 安装 Flask 全部依赖包和自己 cd /path/to/flask/1.0 pip install --no-index --find-links/path/to/downloaded/files Flask1.1.2 cd /path/to/flask/2.0 pip install …

批量输出文件夹内所有文件名和文件——vba实现

导出一个文件夹下所有文件名&#xff0c;可用vba插件实现&#xff0c;如图 如下图&#xff0c;已在桌面生成一个txt文本&#xff0c;但此方法只可输出一级目录下的文件&#xff0c;若输出所有文件&#xff0c;则需修改插件代码 &#xff08;若想导出硬盘下所有文件和文件夹&…

网络通信HTTP

学习内容 这是昨日学习内容&#xff0c;之后花费昨晚和今天一整天的时间做了个小项目 项目&#xff1a;基于网络爬虫的天气查询系统 其中用了cJSON库来解析相关内容&#xff0c;感兴趣的朋友也可以做一做

SM2在线解密工具

SM2加密算法&#xff0c;采用公钥加密、私钥解密&#xff0c;在上一篇文章提到SM2加密工具&#xff0c;对应的这里再次提供SM2的在线解密工具 在线SM2解密工具 这个工具非常强大&#xff0c;不管什么加密模式都能无需指定的直接解密。

yolov10在地平线旭日X3派上的部署和测试(Python版本和C++版本)

0、搭建开发环境 当前的测试根据一下的步骤并修改源码是可以实现yolov8的板端运行&#xff0c;如果不想再搭建环境和测试代码bug上浪费更多的时间可以直接获取本人的测试虚拟机&#xff0c;所有的测试代码、虚拟环境和板端测试工程以全部打包到了虚拟机&#xff0c;需要的可以…

MLP多层感知机与Pytorch实现

参考文章&#xff1a; 1.动手学深度学习——多层感知机&#xff08;原理解释代码详解&#xff09;_多层感知机 代码-CSDN博客 2.4.1. 多层感知机 — 动手学深度学习 2.0.0 documentation 3.深度理解多层感知机&#xff08;MLP&#xff09; | 米奇妙妙屋 1. 神经网络由来 神经网…

Qt Designer的尺寸策略学习笔记

在 PySide6&#xff08;或者 PyQt6&#xff09;中&#xff0c;小部件的 sizePolicy 主要用于控制小部件在布局中的行为&#xff0c;特别是在调整窗口大小时。sizePolicy 由两个主要策略组成&#xff1a;水平策略和垂直策略。它们可以进一步细分为伸展、固定、最小、最大等类型。…