一、简介
本文简单认识JDK8的重要新特性之一——Lambda表达式。 在JDK8之前,Java是不支持函数式编程的,所谓的函数编程,即可理解是将一个函数(也称为“行为”)作为一个参数进行传递。通常我们提及得更多的是面向对象编程,面向对象编程是对数据的抽象(各种各样的POJO类),而函数式编程则是对行为的抽象(将行为作为一个参数进行传递)。在JavaScript中这是很常见的一个语法特性,但在Java中将一个函数作为参数传递这却行不通,好在JDK8的出现打破了Java的这一限制。
二、基础语法:
(x,y) -> {}
左侧是一个小括号,里面是要实现的抽象方法的参数,有几个参数就写几个参数名,无参可写空括号,无需声明参数类型;
中间是一个jdk8新定义的箭头符号;
右侧是一个大括号,在括号内编写抽象方法的实现内容,有参时,可直接使用左侧括号中的对应参数,与正常方法的方法体相同;
三、示例:
// 1. 不需要参数,返回值为 5
() -> 5
// 2. 接收一个参数(数字类型),返回其2倍的值
x -> 2 * x
// 3. 接受2个参数(数字),并返回他们的差值
(x, y) -> x – y
// 4. 接收2个int型整数,返回他们的和
(int x, int y) -> x + y
// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)
(String s) -> System.out.print(s)
四、常用方法(后面在补充)
1、排序
Collections.sort(names, (String a, String b) -> {
return b.compareTo(a);
});
或者
Collections.sort(names, (String a, String b) -> b.compareTo(a));
2、forEach
list3.forEach(student->{
System.out.println(student.getAge());
});
3、stream
Stream(流)是一个来自数据源的元素队列并支持聚合操作,Stream API借助于同样新出现的Lambda表达式,极大的提高编程效率和程序可读性。它提供串行和并行两种模式进行汇聚操作,并发模式能够充分利用多核处理器的优势,使用fork/join并行方式来拆分任务和加速处理过程。通常,编写并行代码很难而且容易出错, 但使用Stream API无需编写一行多线程的代码,就可以很方便地写出高性能的并发程序。
一个流的操作 = 创建流 + 中间操作 + 结果转换
1)创建流:指从集合转换过滤,数值转换过滤、I/O转换、创建等等;
2)中间操作:指对流中的数据进行聚合,如filter\map\sorted\reduce、distinct等等;
3)结果转换:指将流进行输出,打印、转换成array、转换成collection等;
Stream两个基础的特征:
Pipelining: 中间操作都会返回流对象本身。 这样多个操作可以串联成一个管道, 如同流式风格(fluent style)。 这样做可以对操作进行优化, 比如延迟执行(laziness)和短路( short-circuiting)。
内部迭代: 以前对集合遍历都是通过Iterator或者For-Each的方式, 显式的在集合外部进行迭代, 这叫做外部迭代。 Stream提供了内部迭代的方式, 通过访问者模式(Visitor)实现
1)过滤
//过滤年龄大于13的学生
List<Student> list2=list.stream().filter(student -> new Integer(student.getAge())>13).collect(Collectors.toList());
2)排序
//多条件倒叙排序
List<Student> list5=list.stream().sorted(Comparator.comparing(Student::getAge).reversed().thenComparing(Student::getSex)).collect(Collectors.toList());
3)分组
Map<String, List<Student>> groupBy = list.stream().collect(Collectors.groupingBy(Student::getAge));
4)求最值-方式1
Person person = personList.stream().reduce((p1, p2) -> p1.getSalary() > p2.getSalary() ? p1 : p2).get();
5)转string
String collect = list.stream().filter(map1 -> null != map1.get("id")).map(str -> str.get("id").toString()).collect(Collectors.joining(",", "前", "后"));
6)转list
List<Integer> transactionsIds = transactions.parallelStream().filter(t -> t.getType() == Transaction.GROCERY).sorted(comparing(Transaction::getValue).reversed()).map(Transaction::getId).collect(toList());
//方法二(推荐,利用java8新特性) List<String> strings2 = list.stream().map(s -> s.toString()).collect(Collectors.toList());
7)求和
int sum = widgets.stream().filter(w -> w.getColor() == RED).mapToInt(w -> w.getWeight()).sum();
8)去重
numList=dataList.stream().filter(o->o.getNum()!=null).map(SrmHeaderVO::getNum).distinct().collect(Collectors.toList());
9)转数组
Integer[] evens =Stream.of(sixNums).filter(n -> n%2 == 0).toArray(Integer[]::new);
10)转map
Map<Integer, Student> map = list.stream().collect(Collectors.toMap(Student::getId, student -> student));
Map<Integer,User> userMap2 = userList.stream().collect(Collectors.toMap(User::getId,User->User));
指定key-value,value是对象本身,Function.identity()是简洁写法,也是返回对象本身,key 冲突的解决办法,这里选择第二个key覆盖第一个key。
Map<Integer,User> userMap4 = userList.stream().collect(Collectors.toMap(User::getId, Function.identity(),(key1,key2)->key2));
11)string转list
List collect = Arrays.stream(StringUtils.split(s, “,”)).map(s1 -> Integer.valueOf(s1.trim())).collect(Collectors.toList());
//分页
List<User> subList = list.stream().skip((pageNo-1)*pageSize).limit(pageSize).collect(Collectors.toList());
String error = vindatum.getError().stream().map(String::valueOf).collect(Collectors.joining(","));
dataList.stream().map(val -> val.getValue()).collect(Collectors.joining(","))
dataList.stream().collect(Collectors.toMap(SDictDetail::getLabel, SDictDetail::getValue, (k1, k2) -> k2, LinkedHashMap::new));
List<UserTagInfoResponse> resList = dataPage.getRecords().stream().map(e -> {
UserTagInfoResponse resData = MatrixUtils.copyProperties(e, UserTagInfoResponse.class);
resData.setUserTagId(e.getId());
return resData;
}).collect(Collectors.toList());
long count = list.stream().map(BaseDictDetailEntity::getId).filter(item -> !StrUtil.equals(item, request.getDetailId())).count();
List<Long> userIdList = convertPage.getRecords().stream().map(UserGameInfoResponse::getUserId).collect(Collectors.toList());
resPage.getRecords().stream().forEach(e -> {
for (UserBaseInfoResponse user : userList) {
if (e.getUserId().equals(user.getUserId())) {
e.setAvatar(user.getAvatar());
e.setNickName(user.getNickName());
e.setGoodNum(user.getGoodNum());
break;
}
}
});
scriptIds = pageResult.getRecords().stream().distinct()
.map(MerchantStoreCommentEntity::getPlayScriptId).filter(StrUtil::isNotEmpty)
.collect(Collectors.toList());
resData.setUserTagInfoList(e.getUserTagIdList()
.stream()
.filter(userTagMap::containsKey)
.map(userTagId -> {
UserTagInfoResponse userTagInfoResponse = new UserTagInfoResponse();
userTagInfoResponse.setUserTagId(userTagId);
userTagInfoResponse.setUserTagName(userTagMap.get(userTagId));
return userTagInfoResponse;
}).collect(Collectors.toList()));