Java8用起来,你的代码将会简化很多

9 篇文章 1 订阅
1 篇文章 0 订阅

Java8已经诞生好几年了,但我相信很多小伙伴并不熟悉Java8的特性,并将这些特性使用到工作中去。下面介绍一些我使用Java8的一些经验,真的将我的代码简化了很多。

Optional

你是否遇到过这样一个场景:

通过学生获取姓名,然后再通过这个姓名去会员表里面查询,并将查到的会员打一个学生的标记。

你可能会这么写代码

你看上面的代码,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);
}

如果valuenull,那么就会手动创建一个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也一样。这样就避免空指针异常了。

stream()

平时开发不可避免会操作集合,比如将List转成Map,对包装了对象的List按对象指定属性排序等等。NO CODE NO BB,我们来看看下面场景。

将对象组装成List

如果你需要将多个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());
}

将List按指定属性分组

@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()进行分组,测试结果

将List转成Map

@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);

如上代码,memberListmemberListAfterFilter互不干扰。开发更放心😀。

测试结果

求和

@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遍历

原始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));

两种遍历结果为:

putIfAbsent

一般情况下如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的技术小屋");

测试结果:

以上就是今天的全部内容啦,希望能对你在今后的编码中有用。

往期推荐

扫码二维码,获取更多精彩。或微信搜Lvshen_9,可后台回复获取资料

1.回复"java" 获取java电子书;

2.回复"python"获取python电子书;

3.回复"算法"获取算法电子书;

4.回复"大数据"获取大数据电子书;

5.回复"spring"获取SpringBoot的学习视频。

6.回复"面试"获取一线大厂面试资料

7.回复"进阶之路"获取Java进阶之路的思维导图

8.回复"手册"获取阿里巴巴Java开发手册(嵩山终极版)

9.回复"总结"获取Java后端面试经验总结PDF版

10.回复"Redis"获取Redis命令手册,和Redis专项面试习题(PDF)

11.回复"并发导图"获取Java并发编程思维导图(xmind终极版)

另:点击【我的福利】有更多惊喜哦。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值