网站改版业务,科技类公司网站设计,企业网站建设的成本,城厢区住房和城乡建设局网站目录
前言
函数式接口
Lambda 表达式使用实例
简单示例
1. 无参数#xff0c;无返回值
2. 有参数#xff0c;无返回值
3. 无参数#xff0c;有返回值
4. 有参数#xff0c;有返回值
解释#xff1a;
集合框架
1.forEach#xff1a;遍历集合
2.排序#xff1…目录
前言
函数式接口
Lambda 表达式使用实例
简单示例
1. 无参数无返回值
2. 有参数无返回值
3. 无参数有返回值
4. 有参数有返回值
解释
集合框架
1.forEach遍历集合
2.排序对集合中的元素进行排序
3.映射将集合中的每个元素转换成另一种形式
4.使用Lambda 表达式定制优先队列
实现函数式接口 1.Comparator接口
2.Consumer接口
3.Function接口
结尾 前言
Lambda 表达式 是 Java 8 引入的一项新特性它使得 Java 编程语言更加简洁、灵活特别是在处理函数式编程时。Lambda 表达式允许你以一种更加简洁的方式表示匿名函数即没有名字的函数它是 Java 对函数式编程思想的支持。 通俗地总结一下,它的作用就是让JAVA代码变得更加简洁. 本文是笔者对它的简单介绍,受制于笔者自身学识的不足,也许有不充分或者错误的地方,在此先说一声抱歉.笔者会经常审阅自己的博客,尽力确保不会有错误.
以下是它的基础语法:
基本语法: (parameters) - expression 或 (parameters) -{ statements; } 1. paramaters 类似方法中的形参列表这里的参数是函数式接口里的参数。这里的参数类型可以明确的声明 ,也可不声明而由JVM 隐含的推断。另外当只有一个推断类型时可以省略掉圆括号。 2. - 可理解为 “ 被用于 ” 的意思 3. 方法体 可以是表达式也可以代码块是 函数式接口 里方法的实现。代码块可返回一个值或者什么都不反回这里的代码块块等同于方法的方法体。如果是表达式也可以返回一个值或者什么都不反回。 函数式接口
首先科普一下什么是函数式接口 1. 如果一个接口只有一个抽象方法那么该接口就是一个函数式接口 2. 如果我们在某个接口上声明了 FunctionalInterface 注解那么编译器就会按照函数式接口的定义来要求该接 口这样如果有两个抽象方法程序编译就会报错的。所以从某种意义上来说只要你保证你的接口中只 有一个抽象方法你可以不加这个注解。加上就会自动进行检测的。 FunctionalInterface
interface Example {void test();
} Lambda 表达式使用实例 简单示例 1. 无参数无返回值 如果没有参数, 括号里面也就没有值 FunctionalInterface
interface NoArgNoReturn {void doSomething();
}public class Main {public static void main(String[] args) {// Lambda 表达式实现接口NoArgNoReturn action () - System.out.println(无参数无返回值的方法执行);// 调用接口方法action.doSomething();}
}2. 有参数无返回值 有参数,所以括号里面要放置我们的参数 FunctionalInterface
interface WithArgNoReturn {void printMessage(String message);
}public class Main {public static void main(String[] args) {// Lambda 表达式实现接口WithArgNoReturn action (message) - System.out.println(Message: message);// 调用接口方法action.printMessage(Hello, Lambda!);}
}3. 无参数有返回值 和上面的示例类似 FunctionalInterface
interface NoArgWithReturn {int getNumber();
}public class Main {public static void main(String[] args) {// Lambda 表达式实现接口NoArgWithReturn action () - 42; // 返回固定的数字// 调用接口方法并打印返回值System.out.println(The number is: action.getNumber());}
}4. 有参数有返回值 (括号里面是参数 a,b), 然后我们返回 ab的值 FunctionalInterface
interface WithArgsWithReturn {int sum(int a, int b);
}public class Main {public static void main(String[] args) {// Lambda 表达式实现接口WithArgsWithReturn action (a, b) - a b; // 返回两个数的和// 调用接口方法并打印返回值System.out.println(The sum is: action.sum(10, 20));}
}这么做简化在哪里呢?请看如下例子 import java.util.*;FunctionalInterface
interface Example {void test();
}
public class Main {public static void main(String[] args) {Example example new Example() {Overridepublic void test() {System.out.println(这是一个示例);}};example.test();}
}我们这里定义了一个接口 Example然后在 main 方法中创建了一个匿名内部类实现了 Example 接口。这个匿名类的实现是通过 new Example() {} 来完成的。 所以对比能发现,使用Lambda确实可以简化代码. 解释 匿名内部类Anonymous Inner Class是一个没有名字的类通常在实例化时使用。它是类的一个局部实现可以用来简化代码尤其在只需要某个接口的一个临时实现时。 集合框架 1.forEach遍历集合 ListString list Arrays.asList(apple, banana, cherry);
list.forEach(item - System.out.println(item));2.排序对集合中的元素进行排序 ListInteger numbers Arrays.asList(5, 3, 1, 4, 2);
numbers.sort((a, b) - a - b); // 使用 Lambda 表达式进行升序排序
numbers.forEach(System.out::println); // 输出: 1, 2, 3, 4, 53.映射将集合中的每个元素转换成另一种形式 ListString strings Arrays.asList(apple, banana, cherry);
strings.stream().map(String::toUpperCase) // 将字符串转为大写.forEach(System.out::println);4.使用Lambda 表达式定制优先队列 我们在使用PriorityQueue时,通常需要定义这是大根堆还是小根堆,我们可以使用Lambda表达式来简化这个过程 PriorityQueueInteger priorityQueue new PriorityQueue((o1, o2) - o1-o2);PriorityQueueInteger priorityQueue1 new PriorityQueue(new ComparatorInteger()
{Overridepublic int compare(Integer o1, Integer o2) {return o2-o1;}
}); 顺便提一嘴,这个操作为什么list不行呢?因为根据两者的源代码来看 PriorityQueue 实现了比较接口它能够根据你提供的比较规则Comparator来排序元素或者通过元素自身的自然顺序如果元素实现了 Comparable 接口来排序。因此它支持自动排序。 public PriorityQueue(Comparator? super E comparator) {this(DEFAULT_INITIAL_CAPACITY, comparator);} List 不直接实现比较接口它是一个普通的集合类维护元素的插入顺序。要对 List 中的元素进行排序必须显式地调用排序方法比如 list.sort()并提供一个 Comparator 或让元素实现 Comparable 接口。 public interface ListE extends CollectionE 笔者这里也是随意的举几个例子,读者们明白意思就好. 实现函数式接口 Lambda 实现函数式接口也是它的重要功能,笔者接下来举几个例子给读者看看 1.Comparator接口 如果正常地使用该接口,应该是这样的 import java.util.*;class Person {String name;int age;public Person(String name, int age) {this.name name;this.age age;}Overridepublic String toString() {return name : age;}
}public class Main {public static void main(String[] args) {ListPerson people new ArrayList();people.add(new Person(Alice, 30));people.add(new Person(Bob, 25));people.add(new Person(Charlie, 35));// 使用自定义 Comparator 按照年龄排序people.sort(new ComparatorPerson() {Overridepublic int compare(Person o1, Person o2) {return o1.age - o2.age; // 按照年龄升序排序}});// 输出排序后的列表for (Person person : people) {System.out.println(person);}}
}如果使用Lambda 表达式,可以简化为 import java.util.*;public class Main {public static void main(String[] args) {ListPerson people new ArrayList();people.add(new Person(Alice, 30));people.add(new Person(Bob, 25));people.add(new Person(Charlie, 35));// 使用 Lambda 表达式按年龄排序people.sort((o1, o2) - o1.age - o2.age);// 输出排序后的列表for (Person person : people) {System.out.println(person);}}
}小科普:为什么它是函数式接口 我们透过Comparator接口的源码可以看到 boolean equals(Object obj); 他其实还有这么方法,那么这是为什么呢? 答: 这是从 Object 类继承的不属于接口本身定义的抽象方法。 根据 Java 的定义函数式接口的判断依据是其抽象方法的数量而不是它是否包含其他默认方法或静态方法。 继承自 Object 的方法不计入抽象方法equals() 是所有类包括接口的通用方法它属于 Object 类不是 Comparator 定义的抽象方法。 默认方法和静态方法不影响函数式接口的定义 Java 8 引入默认方法和静态方法后它们提供了更多的工具和扩展性但这些都不影响抽象方法的唯一性。 因此Comparator 只有一个抽象方法 compare(T o1, T o2)符合函数式接口的定义。 2.Consumer接口 以下是我的例子: ListString list1 new ArrayList();list1.add(niko);list1.add(bit);list1.add(ropz);list1.add(faker);list1.add(lwx);list1.forEach(new ConsumerString() {Overridepublic void accept(String s) {System.out.println(s);}});list.forEach((s - System.out.println(s)));3.Function接口 FunctionInteger,Integer function x- x *5;System.out.println(function.apply(2));FunctionInteger,Integer function new FunctionInteger, Integer() {Overridepublic Integer apply(Integer integer) {return integer*5;}};System.out.println(function.apply(2));结尾
我不敢恬不知耻地说这是一遍综合介绍Lambda 表达式的博客,因为受制于自身知识有限,我没有完整地拿出很多例子.但我可以说它初步介绍了Lambda 表达式,希望能给阅读到的小白一些总结性的思考.