Java教程 第41页 Java Lambda表达式上下文 lambda表达式可以只在以下四种环境中使用。 赋值上下文 方法调用上下文 返回上下文 转换上下文 赋值上下文 lambda表达式可以显示在赋值运算符的右侧。 public class Main { public static void main(String[] argv) { Calculator iCal = (x,y)-> x + y; System.out.println(iCal.calculate(1, 2)); } } @FunctionalInterface interface Calculator{ int calculate(int x, int y); } 上面的代码生成以下结果。 方法调用上下文 我们可以使用lambda表达式作为方法或构造函数的参数。 public class Main { public static void main(String[] argv) { engine((x,y)-> x / y); } private static void engine(Calculator calculator){ long x = 2, y = 4; long result = calculator.calculate(x,y); System.out.println(result); } } @FunctionalInterface interface Calculator{ long calculate(long x, long y); } 上面的代码生成以下结果。 返回上下文 我们可以在return语句中使用lambda表达式,其目标类型在方法返回类型中声明。 public class Main { public static void main(String[] argv) { System.out.println(create().calculate(2, 2)); } private static Calculator create(){ return (x,y)-> x / y; } } @FunctionalInterface interface Calculator{ long calculate(long x, long y);...
2024-04-01
Java Lambda – Java函数式接口 函数式接口是具有一个方法的接口,用作lambda表达式的类型。 public interface ActionListener extends EventListener { public void actionPerformed(ActionEvent event); } ActionListener 只有一个方法actionPerformed。它是一个函数式接口。无论调用什么单一方法,只要Java编译器具有兼容的方法签名,Java编译器就会将其匹配到您的lambda表达式。 lambda表达式表示函数式接口的实例。 lambda表达式的类型是一个函数式接口类型。 (String str) -> str.length() str.length() 获取一个String参数并返回其长度。 它的类型可以是任何具有抽象方法的函数接口类型,它使用String作为参数并返回int。 以下是这种函数式接口的示例: @FunctionalInterface interface Processor { int getStringLength(String str); } 我们可以为其函数式接口实例赋值lambda表达式。 Processor stringProcessor = (String str) -> str.length(); 例子 在下面的代码中,我们为其函数接口赋值一个lambda表达式。然后我们通过调用函数接口中定义的方法来执行lambda表达式,并传入一个参数。 public class Main { public static void main(String[] argv) { Processor stringProcessor = (String str) -> str.length(); String name = "Java Lambda"; int length = stringProcessor.getStringLength(name); System.out.println(length); } } @FunctionalInterface interface Processor { int getStringLength(String str); } 上面的代码生成以下结果。 注意 lambda表达式本身不能用作独立的表达式。 lambda表达式的类型由编译器推断。 Java函数式接口定义 函数式接口是具有一个抽象方法的接口。 我们不能使用以下类型的方法来声明一个函数式接口: 默认方法 静态方法 从Object类继承的方法 一个函数式接口可以重新声明Object类中的方法。该方法不被视为抽象方法。因此,我们可以声明lambda表达式使用的另一种方法。 考虑 java.util 包中的Comparator类,如下所示: package java.util; @FunctionalInterface public interface Comparator<T> { // An abstract method declared in the functional interface int compare(T o1, T o2); // Re-declaration...
2024-04-01
Java Lambda – Java交叉类型 Java 8引入了一种称为交集类型的新类型。 交叉类型是多种类型的交叉。 交叉路口类型可能在投射中显示为目标类型。 在两种类型之间使用Type1 & Type2,以表示类型1,类型2的交集的新类型。 例子 以下代码使用具有交集类型的转型,创建一个新的合成类型,它是所有类型的子类型。 它创建两个接口,Calculator是一个功能接口,可以与lambda表达式一起使用。另一个称为 NonFunction ,它不是函数接口。 为了创建一个lambda表达式并赋值给 NonFunction ,我们使用& 来创建新的子类型。 交叉路口类型NonFunction & Calculator是一个函数接口。 public class Main { public static void main(String[] argv) { NonFunction nonFunction = (NonFunction & Calculator) (x,y)-> x + y; } } @FunctionalInterface interface Calculator{ long calculate(long x, long y); } interface NonFunction{ } 例2 以下代码通过将 java.io.Serializable 标记接口与我们自己的功能接口相交来创建交集类型。 public class Main { public static void main(String[] argv) { java.io.Serializable ser = (java.io.Serializable & Calculator) (x,y)-> x + y; } } @FunctionalInterface interface Calculator{ long calculate(long x, long y); } 以这种方式,我们使一个lambda表达式可序列化。
2024-04-01
Java Lambda – Java函数接口 Function<T, R> 接口有六个特殊化: IntFunction<R> LongFunction<R> DoubleFunction<R> ToIntFunction<T> ToLongFunction<T> ToDoubleFunction<T> IntFunction<R>, LongFunction<R>, 和 DoubleFunction<R>分别以int,long和double作为参数,它们的返回值在类型R中。 ToIntFunction<T>, ToLongFunction<T>, 和 ToDoubleFunction<T> 取T类型的参数,并分别返回int,long和double。 辅助方法 Function 接口包含以下默认和静态方法: default <V> Function<T,V> andThen(Function<? super R,? extends V> after) default <V> Function<V,R> compose(Function<? super V,? extends T> before) static <T> Function<T,T> identity() andThen()创建一个 Function ,调用当前函数和指定的函数后得到结果。 compose()创建一个 Function ,该函数调用指定的函数,然后调用当前函数并返回结果。 identify()创建一个返回其参数的函数。
2024-04-01
Java Lambda – Java谓词接口 谓词接口包含以下默认和静态方法。 我们可以使用NOT,AND和OR方法来创建基于其他谓词的谓词。 default Predicate<T> negate() default Predicate<T> and(Predicate<? super T> other) default Predicate<T> or(Predicate<? super T> other) static <T> Predicate<T> isEqual(Object targetRef) negate()否定原始谓词的谓词。 and()组合两个具有短路逻辑AND的谓词。 or()组合了具有短路逻辑或的两个谓词。 isEqual()返回一个谓词,根据Objects.equals(Object,Object)测试两个参数是否相等。 我们可以链接上述方法来创建复杂谓词。 例子 以下示例显示如何使用 Predicate 。 import java.util.function.Predicate; public class Main { public static void main(String[] args) { Predicate<String> i = (s)-> s.length() > 5; System.out.println(i.test("www.w3cschool.cn ")); } } 上面的代码生成以下结果。
2024-04-01
Java Lambda – Java静态方法引用 lambda表达式表示在函数接口中定义的匿名函数。 方法引用使用现有方法创建lambda表达式。 方法引用的一般语法是 Qualifier::MethodName 两个连续的冒号充当分隔符。 MethodName 是方法的名称。 限定符告诉在哪里找到方法引用。 例子 例如,我们可以使用 String::length 从 String 类引用length方法。这里 String 是限定符, length 是方法名。 我们只需要指定方法名。 无需指定方法的参数类型和返回类型。 方法引用的目标类型是功能接口。它确定方法的签名并在必要时解析重载的方法。 方法引用类型 有六种类型的方法引用。 TypeName::staticMethod – 引用类的静态方法,接口或枚举 objectRef::instanceMethod – 引用实例方法 ClassName::instanceMethod – 从类中引用实例方法 TypeName.super::instanceMethod – 从对象的父类型引用实例方法 ClassName::new – 引用一个类的构造函数 ArrayTypeName::new – 对指定数组类型的构造函数的引用 静态方法引用 静态方法引用允许我们使用静态方法作为lambda表达式。 静态方法可以在类,接口或枚举中定义。 以下代码定义了两个lambda表达式。 第一个lambda表达式func1是通过定义输入参数x并提供lambda表达式主体来创建的。基本上,这是创建lambda表达式的正常方式。 第二个lambda表达式func2是通过从Integer类引用静态方法创建的。 import java.util.function.Function; public class Main { public static void main(String[] argv) { // Using a lambda expression Function<Integer, String> func1 = x -> Integer.toBinaryString(x); System.out.println(func1.apply(10)); // Using a method reference Function<Integer, String> func2 = Integer::toBinaryString; System.out.println(func2.apply(10)); } } 从Integer类的静态方法的签名如下。 static String toBinaryString(int i) 上面的代码生成以下结果。 例2 以下代码显示了如何使用Integer.sum作为lambda表达式。 import java.util.function.BiFunction; public class Main { public static void main(String[] argv) { // Uses a lambda expression BiFunction<Integer, Integer, Integer> func1 = (x,...
2024-04-01
Java Lambda – Java实例方法引用 我们可以通过两种方式获得一个实例方法引用,从对象实例或从类名。 基本上我们有以下两种形式。 instance::MethodName ClassName::MethodName 这里实例表示任何对象实例。 ClassName 是的名称类,例如 String , Integer 。 实例和 ClassName 称为接收器。更具体地说, instance 被称为有界接收器,而 ClassName 被称为无界接收器。 我们称为实例有界接收器,因为接收器被限制到实例。 ClassName 是未经过排队的接收器,因为接收器以后有界。 绑定实例方法引用 绑定接收器接收器具有以下形式: instance::MethodName 在下面的代码中,我们使用buildin系统函数接口Supplier作为lambda表达式类型。 首先,我们以正常的方式定义一个lambda表达式。 lambda表达式不接受参数,并返回字符串 ‘w3cschool.cn’ 的长度, 我们使用 ‘w3cschool.cn’ 创建一个String实例,并使用它的length方法作为实例方法引用。 绑定意味着我们已经指定了实例。 以下示例显示如何使用没有参数的绑定接收器和方法来创建实例方法引用。 import java.util.function.Supplier; public class Main{ public static void main(String[] argv){ Supplier<Integer> supplier = () -> "www.w3cschool.cn".length(); System.out.println(supplier.get()); Supplier<Integer> supplier1 = "www.w3cschool.cn"::length; System.out.println(supplier1.get()); } } 上面的代码生成以下结果。 例1 以下示例显示如何使用绑定接收器和方法与参数创建实例方法引用。 import java.util.function.Consumer; public class Main{ public static void main(String[] argv){ Util util = new Util(); Consumer<String> consumer = str -> util.print(str); consumer.accept("Hello"); Consumer<String> consumer1 = util::print; consumer1.accept("www.w3cschool.cn"); util.debug(); } } class Util{ private int count=0; public void print(String s){ System.out.println(s); count++; } public void debug(){ System.out.println("count:" + count); } } 上面的代码生成以下结果。 未绑定实例方法引用 未绑定的接收器使用以下语法 ClassName::instanceMethod 它与我们用来引用静态方法的语法相同。...
2024-04-01
Java Lambda – Java构造函数引用 我们可以使用构造函数创建一个lambda表达式。 使用构造函数引用的语法是: ClassName::new 关键字new指的是类的构造函数。编译器根据上下文选择一个构造函数。 import java.util.function.Function; import java.util.function.Supplier; public class Main{ public static void main(String[] argv){ Supplier<String> func1 = () -> new String(); System.out.println("Empty String:"+func1.get()); Function<String,String> func2 = str -> new String(str); System.out.println(func2.apply("www.w3cschool.cn")); Supplier<String> func3 = String::new; System.out.println("Empty String:"+func3.get()); Function<String,String> func4 = String::new; System.out.println(func4.apply("www.w3cschool.cn")); } } 上面的代码生成以下结果。 数组构造函数引用 我们可以使用数组构造函数创建一个数组如下。 ArrayTypeName::new int [] :: new 是调用 new int [] 。 new int [] 需要一个 int 类型值作为数组长度,因此 int [] :: new 需要一个 int 类型输入值。 以下代码使用数组构造函数引用创建一个int数组。 import java.util.Arrays; import java.util.function.IntFunction; public class Main{ public static void main(String[] argv){ IntFunction<int[]> arrayCreator1 = size -> new int[size]; // Creates an int array of five elements int[] intArray1 = arrayCreator1.apply(5); System.out.println(Arrays.toString(intArray1)); IntFunction<int[]> arrayCreator2 = int[]::new; int[] intArray2 = arrayCreator2.apply(5); System.out.println(Arrays.toString(intArray2)); } }...
2024-04-01
Java Lambda – Java通用方法引用 我们可以通过指定实际的类型参数来在方法引用中使用通用方法。 语法如下: ClassName::<TypeName>methodName 通用构造函数引用的语法: ClassName<TypeName>::new 例子 以下代码使用通用的Arrays.asList方法创建lambda表达式,并将参数设置为String。 import java.util.Arrays; import java.util.List; import java.util.function.Function; public class Main{ public static void main(String[] argv){ Function<String[],List<String>> asList = Arrays::<String>asList; System.out.println(asList.apply(new String[]{"a","b","c"})); } } 上面的代码生成以下结果。
2024-04-01
Java Lambda – Java递归Lambda 我们可以在创建递归lambda表达式时使用方法引用。 例子 以下代码以正常方式创建递归函数,然后使用递归函数作为方法引用来创建lambda表达式。最后的lambda表达式成为递归。 import java.util.function.IntFunction; public class Main { public static void main(String[] args) { IntFunction<Long> factorialCalc = Main::factorial; System.out.println(factorialCalc.apply(10)); } public static long factorial(int n) { if (n == 0) { return 1; } else { return n * factorial(n - 1); } } } 上面的代码生成以下结果。
2024-04-01