Java8已经诞生好几年了,但我相信很多小伙伴并不熟悉Java8的特性,并将这些特性使用到工作中去。下面介绍一些我使用Java8的一些经验,真的将我的代码简化了很多。
你是否遇到过这样一个场景:
“通过学生获取姓名,然后再通过这个姓名去会员表里面查询,并将查到的会员打一个学生的标记。 ”
你可能会这么写代码
你看上面的代码,if语句就嵌套了3层。如果需求更复杂,那么if语句可能会嵌套更多。你的代码肯定通不过代码评审,如果你知晓卫语句,你可能会这么写代码
虽然没有if语句嵌套,但还是有if语句啊。你的上司可能会挑骨头,if语句太多,能把if语句去掉吗。冥思苦想之际,突然灵光一闪,Java8有个Optional
类好像可以解决这个问题。于是你开始了测试,终于有了如下代码:
Optional<Student> studentOpt = Optional.ofNullable(student);
String name = studentOpt.map(Student::getName).orElseGet(String::new);
List<Member> members = listByName(name);
Optional.ofNullable(members).orElseGet(ArrayList::new).forEach(m -> {
//给member打上学生标签
doSomething()
});
ofNullable()
源码如下:
public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}
如果value
为null
,那么就会手动创建一个new Optional()
;这里就避免了空指针异常。
orElseGet()
源码如下:
public T orElseGet(Supplier<? extends T> other) {
return value != null ? value : other.get();
}
如果value
值为null,会赋值给一个新值,新值为自己赋的值。
当student
为null时,会创建一个new Optional()
,接下来获取name
,如果name
为null,会创建一个new String()
,接下来member
也一样。这样就避免空指针异常了。
平时开发不可避免会操作集合,比如将List转成Map,对包装了对象的List按对象指定属性排序等等。NO CODE NO BB,我们来看看下面场景。
如果你需要将多个Member
组装成List
,你可能会这么写
上面这么写也没什么不好,但如果你使用了Java8的Stream,组装集合简直是一气呵成。
private List<Member> listMember() {
return Stream.of(
new Member("1", "Lvshen", 10, "订阅号:Lvshen的技术小屋"),
new Member("2", "Lvshen2", 20, "头条号:Lvshen的技术小屋"),
new Member("3", "Lvshen3", 30, "知乎:Lvshen"),
new Member("4", "Lvshen4", 10, "CSDN:Lvshen")
).collect(Collectors.toList());
}
@Test
public void testGroupBy() {
List<Member> memberList = listMember();
Map<Integer, List<Member>> map = memberList
.stream().collect(Collectors.groupingBy(Member::getCode));
System.out.println(map);
}
按member.getCode()
进行分组,测试结果
@Test
public void testMap() {
List<Member> memberList = listMember();
Map<String, Member> memberMap = memberList
.stream().collect(Collectors.toMap(Member::getId, value -> value, (key1, key2) -> key1));
System.out.println(memberMap);
}
按member.getId()
为key转化成Map,测试结果
有这样一个场景:遍历List集合,当元素满足某个条件时,删除该元素。聪明的你肯定会遍历迭代器,然后删除迭代器。
其实这里我建议不要删除元素,可以按条件过滤出新的List
。在方法中尽量不要删除原List
,因为你可能在后面的编码中忘记List
已经删除了部分元素,最后出现了与预期不符的结果。
如何用Java8的stream()
过滤元素?
List<Member> memberList = listMember();
List<Member> memberListAfterFilter = memberList.stream().filter(member -> 10 != member.getCode()).collect(Collectors.toList());
System.out.println(memberListAfterFilter);
如上代码,memberList
和memberListAfterFilter
互不干扰。开发更放心😀。
测试结果
@Test
public void testSum() {
List<Member> memberList = listMember();
int sum = memberList.stream().mapToInt(Member::getCode).sum();
System.out.println(sum);
//如果是BigDecimal
//BigDecimal totalMoney = appleList.stream().map(Apple::getMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
}
普通求和与BigDecimal
求和。测试结果:
70
@Test
public void testMax() {
List<Member> memberList = listMember();
Optional<Member> maxMemberOpt = memberList.stream().collect(Collectors.maxBy(Comparator.comparing(Member::getCode)));
maxMemberOpt.ifPresent(System.out::println);
}
求code
最大的Member
。测试结果:
public void testDistinct() {
//根据特定的属性去重
List<Member> memberList = listMember();
List<Integer> codeList = memberList.stream().map(Member::getCode).collect(Collectors.toList());
List<Integer> afterDistinctList = codeList.stream().distinct().collect(Collectors.toList());
System.out.println(afterDistinctList);
}
测试结果:
[10, 20, 30]
@Test
public void testSort() {
List<Member> memberList = listMember();
//按code排序
List<Member> reversedList = memberList.stream().sorted(Comparator.comparing(Member::getCode).reversed()).collect(Collectors.toList());
System.out.println(reversedList);
}
按code
逆向排序,测试结果:
public void testCount() {
List<Member> memberList = listMember();
Map<Integer, Long> countMap = memberList.stream().collect(Collectors.groupingBy(Member::getCode, Collectors.counting()));
System.out.println(countMap);
}
我们按code
统计出现的次数,测试结果:
{20=1, 10=2, 30=1}
原始Map遍历方式为
List<Member> memberList = listMember();
Map<String, Member> memberMap = memberList
.stream().collect(Collectors.toMap(Member::getId, value -> value, (key1, key2) -> key1));
//原始操作
Set<Map.Entry<String, Member>> entries = memberMap.entrySet();
for (Map.Entry<String, Member> entry : entries) {
System.out.println(entry.getKey()+":"+entry.getValue());
}
Java8的遍历方式一气呵成
//Java8
memberMap.forEach((key,value) -> System.out.println(key+":"+value));
两种遍历结果为:
一般情况下如Map的key存在,下次put,原value值会被覆盖。但如果要求当Map的key存在时,下次put不会覆盖原value值。你肯定会这么写:
Map<String,String> map = Maps.newHashMap();
map.put("key","微信搜:Lvshen_9");
if (map.get("key") == null) {
map.put("key","Lvshen的技术小屋");
}
然而Java8中Map增加了新方法,可以一行解决:
map.putIfAbsent("key", "Lvshen的技术小屋");
测试结果:
以上就是今天的全部内容啦,希望能对你在今后的编码中有用。