前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Java8用起来,你的代码将会简化很多

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

作者头像
Lvshen
发布2022-05-05 17:25:59
发布2022-05-05 17:25:59
60300
代码可运行
举报
运行总次数:0
代码可运行

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

Optional

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

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

你可能会这么写代码

你看上面的代码,if语句就嵌套了3层。如果需求更复杂,那么if语句可能会嵌套更多。你的代码肯定通不过代码评审,如果你知晓卫语句,你可能会这么写代码

虽然没有if语句嵌套,但还是有if语句啊。你的上司可能会挑骨头,if语句太多,能把if语句去掉吗。冥思苦想之际,突然灵光一闪,Java8有个Optional类好像可以解决这个问题。于是你开始了测试,终于有了如下代码:

代码语言:javascript
代码运行次数:0
运行
复制
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()源码如下:

代码语言:javascript
代码运行次数:0
运行
复制
public static <T> Optional<T> ofNullable(T value) {
   return value == null ? empty() : of(value);
}

如果valuenull,那么就会手动创建一个new Optional();这里就避免了空指针异常。

orElseGet()源码如下:

代码语言:javascript
代码运行次数:0
运行
复制
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,组装集合简直是一气呵成。

代码语言:javascript
代码运行次数:0
运行
复制
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按指定属性分组

代码语言:javascript
代码运行次数:0
运行
复制
@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

代码语言:javascript
代码运行次数:0
运行
复制
@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()过滤元素?

代码语言:javascript
代码运行次数:0
运行
复制
List<Member> memberList = listMember();
List<Member> memberListAfterFilter = memberList.stream().filter(member -> 10 != member.getCode()).collect(Collectors.toList());
System.out.println(memberListAfterFilter);

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

测试结果

求和

代码语言:javascript
代码运行次数:0
运行
复制
@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求和。测试结果:

代码语言:javascript
代码运行次数:0
运行
复制
70

求最值

代码语言:javascript
代码运行次数:0
运行
复制
@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。测试结果:

根据特定属性去重

代码语言:javascript
代码运行次数:0
运行
复制
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);
}

测试结果:

代码语言:javascript
代码运行次数:0
运行
复制
[10, 20, 30]

排序

代码语言:javascript
代码运行次数:0
运行
复制
@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逆向排序,测试结果:

统计

代码语言:javascript
代码运行次数:0
运行
复制
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统计出现的次数,测试结果:

代码语言:javascript
代码运行次数:0
运行
复制
{20=1, 10=2, 30=1}

Map遍历

原始Map遍历方式为

代码语言:javascript
代码运行次数:0
运行
复制
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的遍历方式一气呵成

代码语言:javascript
代码运行次数:0
运行
复制
//Java8
memberMap.forEach((key,value) -> System.out.println(key+":"+value));

两种遍历结果为:

putIfAbsent

一般情况下如Map的key存在,下次put,原value值会被覆盖。但如果要求当Map的key存在时,下次put不会覆盖原value值。你肯定会这么写:

代码语言:javascript
代码运行次数:0
运行
复制
Map<String,String> map = Maps.newHashMap();
map.put("key","微信搜:Lvshen_9");
if (map.get("key") == null) {
    map.put("key","Lvshen的技术小屋");
}

然而Java8中Map增加了新方法,可以一行解决:

代码语言:javascript
代码运行次数:0
运行
复制
map.putIfAbsent("key", "Lvshen的技术小屋");

测试结果:

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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-09-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Lvshen的技术小屋 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Optional
  • stream()
    • 将对象组装成List
    • 将List按指定属性分组
    • 将List转成Map
    • 用过滤来代替删除
    • 求和
    • 求最值
    • 根据特定属性去重
    • 排序
    • 统计
    • Map遍历
    • putIfAbsent
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档