使用java8记录

来源:互联网 发布:百度地图js 编辑:程序博客网 时间:2024/06/07 21:52

由于项目组采用java8,最近使用了一些java8的新特性,感觉很赞。理解的不深,简单记录一下自己的使用场景。

1、Stream

stream这个是java8的一个亮点。它把一个集合转化为一个流的形式,然后对这个流进行操作。

list.stream()

这样就把一个list转化为了stream,或者

 Arrays.stream(cityIdsStr.split(","))

把一个字符串的分割转化为一个流。转化为流之后可以干很多的事。

map操作

map操作的目的是把流的每个对象映射为另一种输出流。

 Arrays.stream(cityIdsStr.split(",")).map(i -> Integer.parseInt(i))

map把字符串类型的流元素映射成了integer型,通过Lambda表达式,可以进一步的简写:

Arrays.stream(cityIdsStr.split(",")).map(Integer::parseInt)

这个应该是java8的方法作为参数的写法,具体还没研究。


filter操作

filter是把流中的元素过滤掉不想要的,通过判断条件,留下符合的元素。

Arrays.stream(cityIdsStr.split(",")).map(Integer::parseInt).filter(i -> i > 1)

这里就把所有的小于等于1的元素过滤掉,留下大于1的元素。这里的Lambda表达式也可以简写成方法作为参数的形式。


forEach操作

forEach操作与可以在一般的情况下完成java原来的for循环。

Arrays.stream(cityIdsStr.split(",")).map(Integer::parseInt).filter(i -> i > 1).forEach(i -> System.out.println(i))

也可以化简写为:

Arrays.stream(cityIdsStr.split(",")).map(Integer::parseInt).filter(i -> i > 1).forEach(System.out::println)

在forEach可以做很复杂的操作,操作对象内的属性之类。

这里forEach的概念是terminal类型操作,只能执行一次,经过它之后stream元素就被使用过了,消费掉了,所以不能对一个stream操作进行两次forEach操作。相应的map操作,filter操作为概念上的Intermediate类型操作,可以进行多次。但是如果需要多次forEach的场景怎么办呢?就要用到peek操作。

例如我们要在map之后进行打印,然后在filter操作后再打印一遍。

Arrays.stream(cityIdsStr.split(",")).map(Integer::parseInt).peek(System.out::println).filter(i -> i > 1).peek(System.out::println)

collect操作

collect是把这个流一顿操作之后收集起来,放入一个我们想要的集合中。

List list = Arrays.stream(cityIdsStr.split(",")).map(Integer::parseInt).peek(System.out::println).filter(i -> i > 1).peek(System.out::println).collect(Collectors.toList());

这样就把一顿操作之后的流放到我们常用的list里面去,代码非常的简洁、易读。


2、Optional

当我们写完一段代码之后调试程序之后最常见的bug就是java.lang.NullPointerException而且很多,处理空指针就变得很重要。Optional是java8引入的处理空指针等问题的,和之前的guava的optional相似。

String string = null;Optional<String> stringOptional = Optional.ofNullable(string);

首先做一个空指针,然后用optional处理一下。
输出它是没有问题,针对.length()方法来处理。在这种情况下,调用它的.length()就会抛出空指针。


比较好用的有几个方法:

ofNullable

首先就是这个声明方法,它可以接收一个null,来处理掉,还有一个of方法,接收为null的时候会抛出异常,没有使用过。
然后将这个字符串放入optional里面

String string = null;Optional<String> stringOptional = Optional.ofNullable(string);System.out.println(stringOptional);

如果直接输出字符串是null,而这个输出的结果是Optional.empty是一个optional对象。

ifPresent

ifPresent对处理的optional对象进行判断,如果为空,直接跳过,如果不为空,可以进行操作。

String string = null;Optional<String> stringOptional = Optional.ofNullable(string);stringOptional.ifPresent(value-> System.out.println(value.length()));

如果为空直接跳过,不会抛异常,不为空,调用length方法。


orElse

orElse的作用是当对象为空的时候,返回一个自己可以指定的默认的值。

String string = null;Optional<String> stringOptional = Optional.ofNullable(string);stringOptional.ifPresent(value-> System.out.println(value.length()));System.out.println(stringOptional.orElse("it's null"));

如果不为空,则输出字符串本身,如果为空,输出默认的值”it’s null”
这样我们可以在自己的工程下写一个处理空指针的通用方法。

public static String StringCheck(String str,String defult){    Optional<String> stringOptional = Optional.ofNullable(str);    return stringOptional.orElse(defult); }

通过这个方法处理可能出现空指针的字符串对象,当然也可以做很多不同类型的处理方法。

System.out.println(StringCheck(string,"stringisnull"));

通过调用方法,避免空指针,代码量也没有增加。

在处理集合的时候,我们有时候需要对其进行判断,可能会判断他是否为空,长度是否为0,这样就容易出现空指针,apache的commons.collections4中有一个包装好的判断集合为空的方法。

if (CollectionUtils.isEmpty(list)) {          continue;        }

3、java.time

java时间操作一直使用的是java.util.date,感觉使用起来比较费脑,代码的行数也比较多,一直用的比较多的就是各种格式化,涉及到推后时间的问题,也不怎么好写,而且线程不安全。
这段时间要写一个动态sql,动态的部分是时间,变量传入的是当前时间的前6个月。于是研究了一下java8的时间api。

常用的有LocalDate,LocalTime,LocalDateTime,分别是获取日期,时间,时间和日期。

相比于date的api来说,使用比较方便,代码量也比较少。
获取当前时间

LocalTime localTime = LocalTime.now();

结果就是14:45:52.812,把那个812去掉

LocalTime localTime = LocalTime.now().withNano(0);

结果就是14:45:52

它有很多的方便的方法,获取某个月第一个周一什么的,十分方便。


例如项目中用到的获取当前时间的前六个月,不用管任何跨年之类的麻烦。

LocalDate date = LocalDate.now();LocalDate sqlDate = date.minus(6, ChronoUnit.MONTHS);

和java.sql的映射

SQL -> Java--------------------------date -> LocalDatetime -> LocalTimetimestamp -> LocalDateTime

记得之前用java.util.date映射java.sql的时候,取到日期的需求,还要操作返回的字符串,去掉00:00:00的时间,很麻烦。

java8的java.time使我们操作时间变得流畅简单,还有很多的功能,没有用到,相信应该都很好用。


java8还有很多的比较高深的功能还没有用到,需要的时候再去学习,一定还有一些特性使得变成更加的简易。

原创粉丝点击