Java1.8新特性Optional和stream流操作的用法,为什么要用这些?

Java1.8新特性Optional和stream流操作的用法,为什么要用这些?

Optional和stream流操作都属于1.8的函数式编程的经典实现,在我们结合着Optional和stream操作集合,可以使我们更快的适应lambda表达式

Optional

Optional类常用方法

先看下Optional常用方法简介:

图片来源:JDK1.8新特性值Optional,详细的方法demo这个链接里面也有,刚刚接触这个类的朋友可以学一下。

为什么要用Optional?

一方面是为了使我们代码的简洁、明晰,不会过于臃肿,另一方面1.8为我们提供了更好的判断空指针的方式,是很值得我们在日常开发使用的,举个简单的例子,发现下Optional的妙处:
场景:下单时,判断一个用户地址是浙江杭州才可以下单:
代码:

// 代码1
Person person1 = getPersonByMobile("18888888888");
if (null != person1) {
    
    
    String address = person1.getAddress();
    if (null != address) {
    
    
        if (address.contains("浙江杭州")) {
    
    
            // 执行下单
        }
    } else {
    
    
        throw new CustomRunTimeException("不可下单");
    }
} else {
    
    
    throw new CustomRunTimeException("不可下单");
}
// 代码2
Person person1 = getPersonByMobile("18888888888");
boolean flag = false;
if (null != person1) {
    
    
    String address = person1.getAddress();
    if (null != address) {
    
    
        if (address.contains("浙江杭州")) {
    
    
            flag = true;
        }
    }
}

if(!flag){
    
    
    throw new CustomRunTimeException("不可下单");
}
// 执行下单

代码2在代码明晰上要好很多,可是代码的非空判断还是很多,过于冗余,这时我们就可以使用Optional来处理(好处多多,大家自己体会哈)

String address = Optional.ofNullable(getPersonByMobile("18888888888"))
                .map(person2 -> person2.getAddress())
                .filter(s -> s.contains("浙江杭州"))
                .orElseThrow(() -> new CustomRunTimeException("不可下单"));
// 执行下单

就是这么简单的代码,就实现了和上面较为臃肿的代码同样的功能,而且Optional支持链式调用十分强大

上面optional代码使用的逻辑和大家简单说下,getPersonByMobile(“18888888888”)返回person对象①,
不为null,通过map()方法得到用户的地址数据②,不为null通过filter()判断字符串是否符合过滤条件③,符合,返回字符串给address,期间①②③有一处为null,都会抛出orElseThrow里面的异常。

stream()

stream常用方式

stream()提供了对集合的强大操作方式,如果想深入了解可以参考这篇文章java8 stream常用方法

常见操作

对stream()的各种方法也没一定要具体掌握,主要是在经常使用的操作集合的场景可以灵活运行即可。
下面给出来本人在工作中常见的操作集合的方式,感兴趣的可以拿来练手(由易到难)

// 1、遍历
// 2、 过滤不需要的数据
// 3、按照某个属性排序
// 3.1生成VO类
// 4、得到手机号list,并排序
// 5、是否存在13588438646手机号的用户
// 6、根据手机号组成map
// 7、判断符合条件的数据量
// 8、根据userId组成map,根据key保存的userId可排序

下面是通过stream()来实现

package com.fss.controller.stream;

import com.fss.controller.model.Person;
import com.fss.controller.vo.PersonVO;
import com.sun.org.slf4j.internal.Logger;
import com.sun.org.slf4j.internal.LoggerFactory;
import org.junit.Test;

import java.util.*;
import java.util.stream.Collectors;

public class StreamUseTest {
    
    

    private static Logger logger = LoggerFactory.getLogger(StreamUseTest.class);
    private static List<Person> personList = new ArrayList<>();

    static {
    
    
        personList.add(new Person("hsf", "13583452646", 18, "广州"));
        personList.add(new Person("gkd", "18685642548", 20, "北京"));
        personList.add(new Person("nha", "15545643423", 16, "上海"));
    }

    @Test
    public void test1() {
    
    
        // 1、遍历
        personList.forEach(person -> {
    
    
            System.err.println(person.toString());
        });

        // 2、过滤不需要的数据
        List<Person> filterList = personList.stream().filter(person -> person.getMobile().contains("155456")).collect(Collectors.toList());
        System.err.println(filterList.toString());

        // 3、按照某个属性排序(2、3有时会需要一起使用,过滤并排序)
        List<Person> sortedList = personList.stream().sorted((o1, o2) -> -(o1.getAge() - o2.getAge())).collect(Collectors.toList());
        System.err.println(sortedList.toString());

		// 3.1、生成VO类
		List<PersonVO> personVOList = personList.stream().map(person -> {
    
    
            return PersonVO.builder().personId(person.getPersonId()).name(person.getName()).build();
        }).collect(Collectors.toList());
        System.err.println(personVOList);
        
        // 4、得到手机号list,并排序
        List<String> mobileList = personList.stream().map(person -> person.getMobile()).collect(Collectors.toList()).stream().sorted((o1, o2) -> -o1.compareTo(o2)).collect(Collectors.toList());
        System.err.println(mobileList.toString());

        // 5、是否存在13588438646手机号的用户
        boolean b = personList.stream().anyMatch(person -> person.getMobile().contains("15545643423"));
        System.err.println("是否存在15545643423手机号的用户:" + b);

        // 6、根据手机号组成map
        Map<String, Person> personMap = personList.stream().collect(Collectors.toMap(Person::getMobile, person -> person));
        System.err.println(personMap);

        // 7、判断符合条件的数据量
        long count = personList.stream().filter(person -> person.getMobile().contains("15545643423")).count();
        System.err.println(count);

        // 8、根据userId组成map,id可排序
        Map<Long, PersonVO> personVOMap = personList.stream().collect(Collectors.toMap(Person::getPersonId, person -> PersonVO.builder()
                .personId(person.getPersonId()).address(person.getAddress()).name(person.getName())
                .age(person.getAge()).mobile(person.getMobile()).idCard("34120xxxxxx").build()
        ));
        Map<Long, PersonVO> map = new LinkedHashMap<>();
        personVOMap.entrySet().stream().sorted(Map.Entry.<Long, PersonVO>comparingByKey().reversed()).
                forEachOrdered(longPersonVOEntry -> {
    
    
                    map.put(longPersonVOEntry.getKey(), longPersonVOEntry.getValue());
                });

        System.err.println(map);

    }
}

猜你喜欢

转载自blog.csdn.net/kolbjbe/article/details/115023296