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://www.rhkb.cn/news/387377.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TypeError: Components is not a function

Vue中按需引入Element-plus时&#xff0c;报错TypeError: Components is not a function。 1、参考Element-plus官方文档 安装unplugin-vue-components 和 unplugin-auto-import这两款插件 2、然后需要在vue.config.js中配置webPack打包plugin配置 3、重新启动项目会报错 T…

Java----反射

什么是反射&#xff1f; 反射就是允许对成员变量、成员方法和构造方法的信息进行编程访问。换句话来讲&#xff0c;就是通过反射&#xff0c;我们可以在不需要创建其对象的情况下就可以获取其定义的各种属性值以及方法。常见的应用就是IDEA中的提示功能&#xff0c;当我…

鸿蒙(HarmonyOS)自定义Dialog实现时间选择控件

一、操作环境 操作系统: Windows 11 专业版、IDE:DevEco Studio 3.1.1 Release、SDK:HarmonyOS 3.1.0&#xff08;API 9&#xff09; 二、效果图 三、代码 SelectedDateDialog.ets文件/*** 时间选择*/ CustomDialog export struct SelectedDateDialog {State selectedDate:…

声学气膜馆的优势:卓越声学性能与多样化应用—轻空间

随着科技的发展和人们对音质要求的提高&#xff0c;声学气膜馆逐渐成为现代建筑中的重要组成部分。声学气膜馆不仅在设计和声学性能上有显著优势&#xff0c;还在提高场馆舒适度、增加活动多样性以及带来经济效益方面表现突出。 提升声学环境质量 声学气膜馆通过利用先进的声学…

未来GenAI 怎样逐步改变搜索?

欢迎来到雲闪世界。人工智能的进步正在将传统搜索引擎转变为应答机。这一转变是由网络搜索领域的新老参与者共同推动的&#xff0c;并正在影响世界各地人们获取信息的方式。 谁是基于 GenAI 的搜索的主要参与者&#xff1f;他们如何提出解决方案&#xff1f;这对用户有何影响&a…

18万就能买华为智驾车,你当不了韭菜!

文 | AUTO芯球 作者 | 雷慢 万万没想到啊&#xff0c; 把智能驾驶汽车价格打到最低的&#xff0c; 居然是智驾实力最强的华为&#xff0c; 这你敢信吗 就现在&#xff0c;17.99万就能买华为智驾的车了&#xff0c; 它就是长安和华为合作的首个车型&#xff0c; 深蓝S07…

【Spring Boot教程:从入门到精通】掌握Spring Boot开发技巧与窍门(三)-配置git环境和项目创建

主要介绍了如何创建一个Springboot项目以及运行Springboot项目访问内部的html页面&#xff01;&#xff01;&#xff01; 文章目录 前言 配置git环境 创建项目 ​编辑 在SpringBoot中解决跨域问题 配置Vue 安装Nodejs 安装vue/cli 启动vue自带的图形化项目管理界面 总结 前言 …

十日Python项目——第四日(用户中心—收货地址)

#前言&#xff1a; 在最近十天我会用Python做一个购物类项目&#xff0c;会用到DjangoMysqlRedisVue等。 今天是第四天&#xff0c;主要负责撰写用户中心部分的收货地址部分。若是有不懂大家可以先阅读我的前三篇博客以能够顺承。 若是大家基础有不懂的&#xff0c;小编前面…

01、爬虫学习入门

爬虫&#xff1a;通过编写程序&#xff0c;来获取获取互联网上的资源 需求&#xff1a;用程序模拟浏览器&#xff0c;输入一个网址&#xff0c;从该网址获取到资源或内容 一、入门程序 #使用urlopen来进行爬取 from urllib.request import urlopen url "http://www.ba…

我们的网站被狗爬了!

大家好&#xff0c;我是程序员鱼皮。 世风日下&#xff0c;人心不古。我们的程序员面试刷题网站 《面试鸭》 才刚刚上线了一个多月&#xff0c;就由于过于火爆&#xff0c;被不少同行和小人发起网络攻击。 而且因为我们已经有 4500 多道人工整理的企业高频面试题、100 多个各…

【JavaScript】函数的动态传参

Javacript&#xff08;简称“JS”&#xff09;是一种具有函数优先的轻量级&#xff0c;解释型或即时编译型的编程语言。虽然它是作为开发Web页面的脚本语言而出名&#xff0c;但是它也被用到了很多非浏览器环境中&#xff0c;JavaScript基于原型编程、多范式的动态脚本语言&…

第六周:机器学习周报

机器学习周报 摘要Abstract机器学习——类神经网络训练不起来怎么办&#xff1f;1. 自动调整学习率&#xff08;learning rate&#xff09;1.1 特制化的Learning Rate——parameter dependent1.1.1 Root Mean Square&#xff08;RMS&#xff0c;均方根&#xff09;1.1.2 RMSPro…

Qt Creator使用git管理代码

1.在GitHub中新建仓库&#xff0c;设置好仓库名后&#xff0c;其它的设置默认即可。 2.打开git bash&#xff0c;输入以下命令&#xff1a; git config --global user.name "xxxxx" #设置你的GitHub用户名 git config --global user.email "xxxxxxxxx.…

DMB,DSB,ISB三个指令区别

此部分说明三个指令的具体区别&#xff08;在指令流水线上说明&#xff09;&#xff0c;这三个指令主要目的在于确保程序在多处理器环境下的稳定性和一致性&#xff0c;避免由于指令乱序和内存操作重排引起的不可预测行为 一个简化的流水线&#xff0c;包含以下阶段&#xff1…

[Docker][Docker Registry]详细讲解

目录 1.什么是Docker Registry&#xff1f;2.镜像源配置3.镜像仓库命令1.命令清单2.docker login2.docker pull3.docker push4.docker search5.docker logout 1.什么是Docker Registry&#xff1f; 镜像仓库(Docker Registry) 功能&#xff1a;负责存储、管理和分发镜像&#x…

腾讯云网站/域名备案操作流程

目录 一、备案服务授权二、备案 一、备案服务授权 二、备案 在“我的备案”页面&#xff0c;点击【去备案】&#xff1a; 点击【新增备案】&#xff1a; 点击【同意并继续】&#xff1a; 选择省份&#xff0c;点击【开始备案】&#xff1a; 输入备案相关信息后点击【提交】…

vue给数组对象赋值改变对象里面的数据,数据没有更新this.$set

替换数组startTime的值&#xff1a; 原数据 this.serviceTimeList.push({serviceTimeName: 服务时间段,startTime: this.startTime,endTime: this.endTime,currentDateStart: this.currentDate,currentDateEnd: this.currentDate}) this.$set(this.array, index, newValue); …

笑谈“八股文”,人生不成文

一、“八股文”在实际工作中是助力、阻力还是空谈&#xff1f; 作为现在各类大中小企业面试程序员时的必问内容&#xff0c;“八股文”似乎是很重要的存在。但“八股文”是否能在实际工作中发挥它“敲门砖”应有的作用呢&#xff1f;有IT人士不禁发出疑问&#xff1a;程序员面试…

计算机系统操作系统简介

目录 1.计算机系统简介 1.1组成结构 1.2系统软件 1.3冯诺依曼计算机特点 1.4硬件构架 2.硬件的进一步认识 2.1存储器 2.2输入设备 2.3输出设备 2.4CPU组成 2.5线的概念引入 3.操作系统 3.1操作系统简介 3.2操作系统如何管理 3.3库函数和系统调用 1.计算机系统简介…

Linux shell编程学习笔记67: tracepath命令 追踪数据包的路由信息

0 前言 网络信息是电脑网络信息安全检查中的一块重要内容&#xff0c;Linux和基于Linux的操作系统&#xff0c;提供了很多的网络命令&#xff0c;今天我们研究tracepath命令。 Tracepath 在大多数 Linux 发行版中都是可用的。如果在你的系统中没有预装&#xff0c;请根据你的…