java8新特性之lambda表达式
Java 8的一个大亮点是引入Lambda表达式,使用它设计的代码会更加简洁。当开发者在编写Lambda表达式时,也会随之被编译成一个函数式接口演示代码下载地址:https://github.com/prettyRain/java8demo.git1.引入lambda表达式1)用接口Runnable演示@Testpublic void test6(){/...
·
目录
Java 8的一个大亮点是引入Lambda表达式,使用它设计的代码会更加简洁。当开发者在编写Lambda表达式时,也会随之被编译成一个函数式接口
演示代码下载地址:https://github.com/prettyRain/java8demo.git
1.引入lambda表达式
1)用接口Runnable演示
@Test
public void test6(){
//以前的匿名内部类
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("lambda");
}
};
runnable.run();
//现在的lambda表达式
Runnable runnable1 = () -> System.out.println("lambda");
runnable1.run();
}
2)自己写接口演示普通调用、匿名内部类调用、lambda表达式调用
Student类 用于演示的学生对象
package com.ge.lambda;
import java.math.BigDecimal;
/**
* 学生类
*/
public class Student {
public static String getStr(Integer grade){
if(Integer.compare(grade,60) > 0){
return "三好学生";
}
return "不及格";
}
private Long id;//id
private String name;//学生姓名
private String sex;//性别
private Integer age;//年龄
private BigDecimal price;//工资
public Student() {
}
public Student(Long id, String name, String sex, Integer age, BigDecimal price) {
this.id = id;
this.name = name;
this.sex = sex;
this.age = age;
this.price = price;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
if (!id.equals(student.id)) return false;
if (!name.equals(student.name)) return false;
if (!sex.equals(student.sex)) return false;
if (!age.equals(student.age)) return false;
return price.equals(student.price);
}
@Override
public int hashCode() {
int result = id.hashCode();
result = 31 * result + name.hashCode();
result = 31 * result + sex.hashCode();
result = 31 * result + age.hashCode();
result = 31 * result + price.hashCode();
return result;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", sex='" + sex + '\'' +
", age=" + age +
", price=" + price +
'}';
}
}
接口 FilterStudent
package com.ge.lambda;
/**
* 接口
*/
public interface FilterStudent<T> {
public boolean test(T t);
}
FilterStudentForAgeImpl 判断年龄接口实现类
package com.ge.lambda;
import java.math.BigDecimal;
/**
* 判断学生工资的实现类
*/
public class FilterStudentForPriceImpl implements FilterStudent<Student> {
@Override
public boolean test(Student student) {
if(student.getPrice().compareTo(new BigDecimal(5000)) >= 0){
return true;
}
return false;
}
}
普通调用、匿名内部类调用、lambda表达式调用
Student[] aa = new Student[]{new Student(1L,"小明","男",18,new BigDecimal(5000)),
new Student(2L,"小花","女",12,new BigDecimal(6000)),
new Student(3L,"小李","男",10,new BigDecimal(3000)),
new Student(4L,"小刘","男",17,new BigDecimal(9000)),
new Student(5L,"小刚","男",13,new BigDecimal(8000))};
//策略设计模式
public List<Student> filterStudent(List<Student> students,FilterStudent<Student> filterStudent){
List<Student> studentList = new ArrayList<Student>();
for(Student student:students){
if(filterStudent.test(student)){
studentList.add(student);
}
}
return studentList;
}
/**
* 普通调用实现类
*/
@Test
public void test3(){
List<Student> listForAge = filterStudent(stus,new FilterStudentForAgeImpl());
for(Student student:listForAge){
System.out.println(student.toString());
}
System.out.println("-----------------------------");
List<Student> listForPrice = filterStudent(stus,new FilterStudentForPriceImpl());
for(Student student:listForPrice){
System.out.println(student.toString());
}
}
/**
* 通过匿名类实现
*/
@Test
public void test4(){
List<Student> list = filterStudent(stus,new FilterStudent<Student>(){
@Override
public boolean test(Student student) {
if(student.getAge() > 13){
return true;
}
return false;
}
});
for(Student student:list){
System.out.println(student.toString());
}
}
/**
* lambda表达式调用
*/
@Test
public void test5(){
List<Student> list = filterStudent(stus,(e) -> e.getAge() >= 12 );
for(Student student:list){
System.out.println(student.toString());
}
System.out.println("-------------------------");
List<Student> list1 = filterStudent(stus,(e) -> e.getPrice().compareTo(new BigDecimal(8000)) >= 0 );
for(Student student:list1){
System.out.println(student.toString());
}
}
2.lambda表达式六种语法格式:
- 1)lambda表达式的基本语法
- 箭头操作符将lambda表达式拆分成两部分;
左侧:lambda表达式的参数列表
右侧:lambda表达式中所需要执行的功能,即lambda体
- 箭头操作符将lambda表达式拆分成两部分;
- 2)语法格式:
- 语法格式一:无参数,无返回值
() -> System.out.println("Hello Lambda!"); - 语法格式二:有一个参数,并且无返回值
(x) -> System.out.println(x) - 语法格式三:若只有一个参数,小括号可以省略不写
x -> System.out.println(x) - 语法格式四:有两个以上参数,有返回值,并且lambda体中有多条语句
Comparator<Integer> com = (x, y) -> {
System.out.println("函数式接口");
return Integer.compare(x, y);
}; - 语法格式五:若 Lambda 体中只有一条语句,有返回值, return 和 大括号都可以省略不写
Comparator<Integer> com = (x, y) -> Integer.compare(x, y); - 语法格式六:Lambda 表达式的参数列表的数据类型可以省略不写,因为JVM编译器通过上下文推断出,数据类型,即“类型推断”
(Integer x, Integer y) -> Integer.compare(x, y);
- 语法格式一:无参数,无返回值
package com.ge.lambda;
import org.junit.Test;
import java.util.Comparator;
import java.util.function.Consumer;
/*
* 一、Lambda 表达式的基础语法:Java8中引入了一个新的操作符 "->" 该操作符称为箭头操作符或 Lambda 操作符
* 箭头操作符将 Lambda 表达式拆分成两部分:
* 左侧:Lambda 表达式的参数列表
* 右侧:Lambda 表达式中所需执行的功能, 即 Lambda 体
* 语法格式一:无参数,无返回值
* () -> System.out.println("Hello Lambda!");
* 语法格式二:有一个参数,并且无返回值
* (x) -> System.out.println(x)
* 语法格式三:若只有一个参数,小括号可以省略不写
* x -> System.out.println(x)
* 语法格式四:有两个以上的参数,有返回值,并且 Lambda 体中有多条语句
* Comparator<Integer> com = (x, y) -> {
* System.out.println("函数式接口");
* return Integer.compare(x, y);
* };
*
* 语法格式五:若 Lambda 体中只有一条语句,有返回值, return 和 大括号都可以省略不写
* Comparator<Integer> com = (x, y) -> Integer.compare(x, y);
*
* 语法格式六:Lambda 表达式的参数列表的数据类型可以省略不写,因为JVM编译器通过上下文推断出,数据类型,即“类型推断”
* (Integer x, Integer y) -> Integer.compare(x, y);
*
*
* 二、Lambda 表达式需要“函数式接口”的支持
* 函数式接口:接口中只有一个抽象方法的接口,称为函数式接口。 可以使用注解 @FunctionalInterface 修饰
* 可以检查是否是函数式接口
*/
public class TestLambda2 {
/**
* 无参 无返回值
*/
@Test
public void test1(){
Runnable r = () -> System.out.println("lambda");
r.run();
}
/**
* 有一个参数,并且无返回值
*/
@Test
public void test2(){
Consumer<String> con = (x) -> System.out.println(x);
con.accept("有一个参数,并且无返回值");
}
/**
* 若只有一个参数,小括号可以省略不写
*/
@Test
public void test3(){
Consumer<String> con = x -> System.out.println(x);
con.accept("若只有一个参数,小括号可以省略不写");
}
/**
* 有两个以上的参数,有返回值,并且 Lambda 体中有多条语句
*/
@Test
public void test4(){
Comparator<Integer> comparator = (x,y) -> {
System.out.println("函数式接口");
return Integer.compare(x,y);
};
System.out.println(comparator.compare(5,6));
}
/**
* 若 Lambda 体中只有一条语句,有返回值, return 和 大括号都可以省略不写
*/
@Test
public void test5(){
Comparator<Integer> comparator = (x,y) -> Integer.compare(x,y);
System.out.println(comparator.compare(5,6));
}
/**
* Lambda 表达式的参数列表的数据类型可以省略不写,因为JVM编译器通过上下文推断出,数据类型,即“类型推断”
*/
@Test
public void test6(){
Comparator<Integer> comparator = (Integer x,Integer y) -> Integer.compare(x,y);
System.out.println(comparator.compare(5,6));
}
}
3.java8内置的四大核心函数式接口
- 1)Consumer<T> : 消费型接口
方法: void accept(T t) - 2)Supplier<T> : 供给型接口
方法: T get(); - 3)Function<T, R> : 函数型接口
方法: R apply(T t); - 4)Predicate<T> : 断言型接口
方法: boolean test(T t);
package com.ge.lambda;
import org.junit.Test;
import javax.print.DocFlavor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
/*
* Java8 内置的四大核心函数式接口
*
* Consumer<T> : 消费型接口
* void accept(T t);
*
* Supplier<T> : 供给型接口
* T get();
*
* Function<T, R> : 函数型接口
* R apply(T t);
*
* Predicate<T> : 断言型接口
* boolean test(T t);
*
*/
public class TestLambda3 {
/**
* Consumer<T>消费型接口
*/
@Test
public void test1(){
Consumer<String> consumer = x -> System.out.println(x);
consumer.accept("consumer消费型接口");
}
/**
* Supplier<T>供给型接口
*/
@Test
public void test2(){
Supplier<Integer> supplier= () -> (int)(Math.random()*100);
System.out.println(supplier.get());
}
/**
* Function(T,R)函数型接口
*/
@Test
public void test3(){
String resultstr = strHander("jjfsdjsjdsjiojwijf",(x) -> x.substring(2,5));
System.out.println(resultstr);
}
public String strHander(String str, Function<String,String> fun){
return fun.apply(str);
}
/**
* 断言型接口
*/
@Test
public void test4(){
List<String> list = Arrays.asList("aaa","bbb","cccc","dddd");
List<String> returnlist = getList(list,(x) -> x.length() > 3);
System.out.println(Arrays.toString(returnlist.toArray()));
}
public List getList(List<String> list, Predicate<String> predicate){
ArrayList<String> returnlist = new ArrayList();
for(String str:list){
if(predicate.test(str)){
returnlist.add(str);
}
}
return returnlist;
}
}
4.方法引用、构造器引用、数组引用
- 1)方法引用:若lambda体中的功能,已经有方法提供了实现,可以使用方法引用(可以理解为lambda表达式的另一种表现形式)
- 1.对象的引用::实例方法名
- 2.类名::静态方法名
- 3.类名::实例方法名
- 注意:①方法引用所引用的方法的参数列表与返回值类型,需要与函数式接口中抽象方法的参数列表和返回值类型保持一致!
②若Lambda 的参数列表的第一个参数,是实例方法的调用者,第二个参数(或无参)是实例方法的参数时,格式: ClassName::MethodName
- 2)构造器引用:构造器的参数列表,需要与函数式接口中参数列表保持一致
- 1.类名::new
- 3)数组引用
- 1.类型[]::new
/**
* 对象的引用 :: 实例方法名
*/
@Test
public void test1(){
//消费型
Consumer<String> consumer = (x) -> System.out.println(x);
Consumer<String> consumer1 = System.out::println;
consumer.accept("consumer:以前的写法");
consumer.accept("consumer1:现在的写法");
//供给型
Student student = new Student(1l,"小明","男",12,new BigDecimal(2000));
Supplier<String> supplier = student::getName;
System.out.println(supplier.get());
}
/**
* 类名 :: 静态方法名
*/
@Test
public void test2(){
//函数型接口
Function<Integer,String> fun = Student::getStr;
System.out.println(fun.apply(100));
}
/**
* 类名 :: 实例方法名 把类名当一个参数来处理
*/
@Test
public void test3(){
//断言型接口
BiPredicate<String,String> biPredicate = (x,y) -> x.equals(y);
System.out.println(biPredicate.test("222","333"));
BiPredicate<String,String> biPredicate1 = String::equals;
System.out.println(biPredicate1.test("222","333"));
Function<Student,String> fun = (e) -> e.toString();
System.out.println(fun.apply(new Student(1l,"小明","男",12,new BigDecimal(2000))));
Function<Student,String> fun1 = Student::toString;
System.out.println(fun.apply(new Student(1l,"小明","男",12,new BigDecimal(2000))));
}
/**
* 构造器引用
*/
@Test
public void test4(){
Supplier<Student> supplier = () -> new Student(1l,"小明","男",12,new BigDecimal(2000));
System.out.println(supplier.get().toString());
Supplier<Student> studentSupplier = Student::new;
System.out.println(studentSupplier.get().toString());
}
/**
* 数组引用
*/
@Test
public void test5(){
//函数型接口
Function<Integer,String[]> function = (x) -> new String[x];
System.out.println(function.apply(3).length);
Function<Integer,String[]> function1 = String[]::new;
System.out.println(function1.apply(3).length);
}
5 合并数组和去重
{
return data
.stream()
.collect(Collectors.groupingBy(WorkOrderModel::getWorkOrderType))
.entrySet()
.stream()
.map(item -> {
Integer workOrderTyepe = item.getKey();
List<GroupsItem> groupsItemList = item
.getValue()
.stream()
.map(ele -> ele.getGroups().stream()
.map(el -> {
GroupsItem groupsItem = new GroupsItem();
BeanUtils.copyProperties(el, groupsItem);
groupsItem.setWosId(ele.getId());
return groupsItem;
})
.collect(Collectors.toList()))
.collect(Collectors.toList())
.stream()
.collect(ArrayList<RuleObj>::new, ArrayList::addAll, ArrayList::addAll);
if (CollectionUtils.isEmpty(groupsItemList)) {
return null;
}
groupsItemList.sort((o1, o2) -> o2.getUpdatedAt().compareTo(o1.getUpdatedAt()));
Map<String, GroupsItem> groupsItemMap = new HashMap<>();
for (GroupsItem group : groupsItemList) {
String key = group.getKey();
GroupsItem groupsItem = groupsItemMap.get(key);
if (groupsItem != null) {
continue;
}
groupsItemMap.put(key, group);
}
return new OrderGroups(workOrderTyepe, rebuildGroupMaps(groupsItemMap));
})
.filter(Objects::nonNull)
.collect(Collectors.toMap(OrderGroups::getTemplateId, OrderGroups::getGroupsItemMap));
}
如上代码所示可以通过(对内部的两个数组进行合并)
.collect(ArrayList::new, ArrayList::addAll, ArrayList::addAll);
去重
List<ImageInfo> imageList = remoteDcoreService.getDriverImages(driverInfo.getDriverId());
imageList = imageList
.stream()
.collect(Collectors.collectingAndThen(Collectors.toCollection(()
-> new TreeSet<>(Comparator.comparing(ImageInfo::getType))), ArrayList::new));
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
已为社区贡献4条内容
所有评论(0)