学会使用Java8新特性

1.为什么要学习Java8中的新特性,在快速更新的年代,技术要想不被淘汰,就需要不断的更新知识,而Java8中需要新的特性,能够大大的简化编程。并且在项目中依旧使用Java6,Java7,这只能证明这整个开发团队学习态度有问题,不管是因为什么原因,如果仅仅是因为升级Java8有风险,而不去做的话,只能抱着陈旧的知识,被这个时代所淘汰。这里有一个观点,需要不断的更新,优化自己的项目,只有将这个项目朝着更好的方法做,这个项目才有价值,否则仅仅开发完了就扔掉的项目,那是没有任何价值,也不能给你带来新的知识,只是有熟悉了一遍以前做过的事情,不能使自己成长。接下来聊一下Java需要理解的特性:
2.需要知道Java8新特性:

  • Stream Api,集合的流式处理
  • Lambda 表达式
  • 加强对日期与时间的处理

Stream Api

首先一个例子

list.stream().filter(user->user.getAge() > 18).map(user->user.getName()).collect(Collectors.toList());

上面例子表达的是list是一个集合,从中过滤出年龄大于18的用户,并获取其中的姓名。一行代码可以搞定以前的for循环和if判断。
list.Stream() //将list转化为流
filter,map聚合操作
collect 终端操作,即将流转化成集合的操作。

1. 流的特性:

1.仅一次使用,后续无法再次使用该流。可以比作成一条操作流水线,最后消费掉之后,不无法在此使用。
2.内部采用迭代的方式。

2.流的操作

流的操作分为中间操作和终端操作,中间操作是对流的处理,终端操作是获取流的结果。

流的生成
Stream<String> of = Stream.of("Java","Spring"); //通过值创建流
Stream<Integer> of = Arrays.stream({1,2,3});//通过数组创建流
Stream<User> stream = list.stream();  //通过集合创建流
Stream<String> lines = Files.lines(Paths.get("data.txt"), Charset.defaultCharset()); //通过文件流创建
方法的引用

在流中操作对象时,可以通过user.getAge()方法操作外,还有其他方式操作

lambda等效的方法引用
(Apple a) -> a.getWeight()Apple::getWeight
() -> Thread.currentThread().dumpStack()Thread.currentThread()::dumpStack
(str,i) -> str.substring(i)String::substring
(String s) -> System.out.println(s)System.out::println

方法的引用分三种:

  1. 指向静态方法的方法引用,例如Integer的parseInt方法,可以写成Integer::parseInt
  2. 指向任意类型实例方法的方法引用,例如String的length方法,可以写成String::length
  3. 指向现有对象的实例方法的引用方法,例如User::getAge
    方法引用一般情况下是可以简写的,例如:list.stream().filter((User u) -> u.getAge() > 0);可以简写成list.stream().filter( u -> u.getAge() > 0); 编译器是可以识别的。
中间操作
  1. filter 过滤,将流中的数据已某个条件过滤出来,不符合条件的就筛选掉。
    List<User> users = list.stream().filter(user->user.getAge()>18).collect(Collectors.toList());
  1. map 映射,选取流中某个对象的字段
    List<String> names = list.stream().map(user->user.getName()).collect(Collectors.toList());
  1. distinct()去重
    List<User> users = list.stream().distinct().collect(Collectors.toList());
  1. 跳过skip(n),截取条数limit(n)
    List<User> users = list.stream().skip(10).limit(5).collect(Collectors.toList());
  1. 合并流,flatMap()是将其他流合并到当前流中进行计算
    list.stream().flatMap(user.stream).collect(Collectors.toList());
  1. 排序sorted()使用
   list.stream().map(user->user.getName()).sort().collect(Collectors.toList()); //sort()使用自然排序
   list.stream().sorted(Comparator.comparing(Student::getAge)) ;// age从小到到排序
终端操作

终端操作就是一个类似收集器一样,在经过前面的一系列的操作之后,将流生成一个可以操作的集合或者是数据。

  1. 汇总
list.stream().collect(Collectors.toList());// 流转变为list集合
list.stream().count;	//获取流中的个数
//获取年龄最大的用户,User::getAge,方法的引用可以写成该样式,如果需要使用
Comparator<User> comparator = Comparator.comparingInt(User::getAge);
Optional<User> maxUser = list.stream().collect(maxBy(comparator));
//获取年龄最小的用户
Comparator<User> comparator = Comparator.comparingInt(User::getAge);
Optional<User> maxUser = list.stream().collect(minBy(comparator));
//用户的年龄之和
int ages = list.stream.collect(summingInt(User::getAge));
//用户的年龄的平均值
int aver= list.stream.collect(averagingInt(User::getAge));
//统计用户的个数,总和,平均值,最大值,最小值
list.stream.collect(summarizingInt(User::getAge));

//连接字符串
list.stream.map(User::getName).collect(joining(“,”));//姓名以逗号分隔

//分组
Map<String,List<User>>maps = list.stream.collect(groupingBy(User::getName)); //以姓名进行分组
Map<String,Long>maps = list.stream.collect(groupingBy(User::getName,counting())); //以姓名进行分组,并计算每个组汇中的个数,二级分组,即在分组之后对集合进行操作。

小结:流的操作能够能够极大的简化代码,对于之后集合中for if的操作,stream的操作完全可以进行替代。一行代码能够解决,使得代码更简洁更容易读懂。

Lambda 表达式

在使用到接口的使用,都需要实现一下接口的方法(特指只有一个方法的接口)例如:

new Thread(new Runnable() {
     @Override
     public void run() {
         System.out.println("Hello World!");
     }
 });

该代码紧紧只输出一行代码,但是其他代码都是废话,在实际上都不需要,lambda就能够简化

new Thread(() ->System.out.println("Hello World!") );

为什么能够这样写 ,首先我只关心传入的参数,如果没有参数,那么其实都不需要关心接口的名词是是什么,可以看下一个:

Comparator<User> comparator= new Comparator<User>(){
	public int compare(User a1,User a2){
		return a1.getAge().compareTo(a2.getAge());
	}
}

转化为lambda表达式:

Comparator<User> comparator = (User a1,User a2) -> a1.getAge().compareTo(a2.getAge());

这个时候代码看起来简洁了,同时也因为Java有类型推断,不用关心User,更洁净的方式:

Comparator<User> comparator = (a1,a2) -> a1.getAge().compareTo(a2.getAge());

通过上面两个例子,自己可以构建一个方法,而只要这个接口只有一个方法,那么就能够在使用过程中使用Lambda。
Java内置了一些有用的Lambda表达式,但常用的有两个:
Comsumer T -> void
Function <T,R> T -> R
lambda表达式其实是一个方法,既然是方法,就需要去有人调用,在一个地方new出该表达式,在需要的地方消费。

List<Consumer<Void>> list = new ArrayList<>();  //Consumer<Void>中Void为空,标识什么都不传
list.add(v-> System.out.println("hello world!"));
for(Consumer<Void> v: list){
	v.accept(null);   //将lambda消费掉,需要捕获异常
}

先产生lambda表达式,然后进行消费掉,这里仅仅只是演示了lambda中Consumer的使用,而这一使用极大的改变了写代码的思路,不在需要写一个接口。

增强的时间类

为什么要使用Java8增强的时间类,第一java.util.Date是可变类型,SimpleDateFormat是非线程安全的。并且操作起来麻烦。

  • LocalDateTime:存储了日期和时间,如:2013-10-15T14:43:14.539
  • LocalDate:存储了日期,如:2013-10-15
  • LocalTime:存储了时间,如:14:43:14.539
    创建时间类:
   LocalDateTime localDateTime = LocalDateTime.now();
   System.out.println("localDateTime :" + localDateTime);
    
   LocalDate localDate = LocalDate.now();
   System.out.println("localDate :" + localDate);
    
   LocalTime localtime = LocalTime.now();
   System.out.println("localtime :" + localtime);

下面 也可以通过Date转化而来。

 public void UDateToLocalDateTime() {
    java.util.Date date = new java.util.Date();
    Instant instant = date.toInstant();
    ZoneId zone = ZoneId.systemDefault();
    LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone);
}

// 02. java.util.Date --> java.time.LocalDate
public void UDateToLocalDate() {
    java.util.Date date = new java.util.Date();
    Instant instant = date.toInstant();
    ZoneId zone = ZoneId.systemDefault();
    LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone);
    LocalDate localDate = localDateTime.toLocalDate();
}

// 03. java.util.Date --> java.time.LocalTime
public void UDateToLocalTime() {
    java.util.Date date = new java.util.Date();
    Instant instant = date.toInstant();
    ZoneId zone = ZoneId.systemDefault();
    LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone);
    LocalTime localTime = localDateTime.toLocalTime();
}

下面来看一些时间的转化的方法:

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class NDateu {

  private static final Logger logger = LoggerFactory.getLogger(NDateu.class);
  //
  public static final long SECOND = 1 * 1000;
  public static final long MINUTE = 60 * SECOND;
  public static final long HOUR = 60 * MINUTE;
  public static final long DAY = 24 * HOUR;
  public static final long WEEK = 7 * DAY;

  /**
   * 获取当前时间.
   */
  public static final String nowTime() {
    LocalDate now = LocalDate.now();
    return now.toString();
  }

  /**
   * 入参格式: Sat Nov 01 14:01:55 CST 2014.
   */
  public static final LocalDateTime parseLocale(String date) {
    if (date == null) {
      return null;
    }
    try {
      DateTimeFormatter formatter = DateTimeFormatter
          .ofPattern("MM dd HH:mm:ss zzz yyyy", Locale.US);
      return LocalDateTime.parse(date, formatter);
    } catch (Exception e) {
        logger.debug("{}, date: {}", Misc.trace(e), date);
      return null;
    }
  }

  /**
   * 入参格式: yyyyMMdd.
   */
  public static final LocalDateTime parseDateyyyyMMdd(String date) {
    if (date == null) {
      return null;
    }
    try {
      DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
      return LocalDateTime.parse(date, formatter);
    } catch (Exception e) {
        logger.debug("{}, date: {}", Misc.trace(e), date);
      return null;
    }
  }

  /**
   * 入参格式: yyyy-MM-dd.
   */
  public static final LocalDateTime parseDateyyyy_MM_dd(String date) {
    if (date == null) {
      return null;
    }
    try {
      DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
      return LocalDateTime.parse(date, formatter);
    } catch (Exception e) {
        logger.debug("{}, date: {}", Misc.trace(e), date);
      return null;
    }
  }

  /**
   * 解析yyyyMMddHH格式的日期.
   */
  public static final LocalDateTime parseDateyyyyMMddHH(String date) {
    if (date == null) {
      return null;
    }
    try {
      DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHH");
      return LocalDateTime.parse(date, formatter);
    } catch (Exception e) {
        logger.debug("{}, date: {}", Misc.trace(e), date);
      return null;
    }
  }

  /**
   * 解析yyyyMMddHHmm格式的日期.
   */
  public static final LocalDateTime parseDateyyyyMMDDHHmm(String date) {
    if (date == null) {
      return null;
    }
    try {
      DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMDDHHmm");
      return LocalDateTime.parse(date, formatter);
    } catch (Exception e) {
        logger.debug("{}, date: {}", Misc.trace(e), date);
      return null;
    }
  }

  /**
   * 解析yyyyMMddHHmmss格式的日期.
   */
  public static final LocalDateTime parseDateyyyyMMDDHHmmss(String date) {
    if (date == null) {
      return null;
    }
    try {
      DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMDDHHmmss");
      return LocalDateTime.parse(date, formatter);
    } catch (Exception e) {
        logger.debug("{}, date: {}", Misc.trace(e), date);
      return null;
    }
  }

  /**
   * 解析yyyy-MM-dd HH:mm:ss格式的日期.
   */
  public static final LocalDateTime parseDateyyyy_MM_dd_HH_mm_ss(String date) {
    if (date == null) {
      return null;
    }
    try {
      DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
      return LocalDateTime.parse(date, formatter);
    } catch (Exception e) {
        logger.debug("{}, date: {}", Misc.trace(e), date);
      return null;
    }
  }

  /**
   * 返回格式: yyyy-MM-dd.
   */
  public static final String parseDateyyyy_MM_dd(LocalDate date) {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    return NDateu.parseLocalDate(formatter, date);
  }

  /**
   * 返回格式: yyyy-MM.
   */
  public static final String parseDateyyyy_MM(LocalDate localDate) {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM");
    return NDateu.parseLocalDate(formatter, localDate);
  }

  /**
   * 返回格式:yyyy-MM-dd HH:mm:ss.
   */
  public static final String parseDateyyyy_MM_ddHHmmss(LocalDateTime localDateTime) {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    return NDateu.parseLocalDateTime(formatter, localDateTime);
  }

  /**
   * 返回格式:yyyy-MM-dd HH:mm.
   */
  public static final String parseDateyyyy_MM_ddHHmm(LocalDateTime localDateTime) {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
    return NDateu.parseLocalDateTime(formatter, localDateTime);
  }

  /**
   * 返回格式:yyyy/MM/dd HH:mm.
   */
  public static final String parseDateyyyyMMddHHmm2(LocalDateTime localDateTime) {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm");
    return NDateu.parseLocalDateTime(formatter, localDateTime);
  }

  /**
   * 返回格式:yyyy/MM/dd HH:mm:ss.
   */
  public static final String parseDateyyyyMMddHHmmss3(LocalDateTime localDateTime) {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
    return NDateu.parseLocalDateTime(formatter, localDateTime);
  }

  /**
   * 返回格式:yyyyMMdd.
   */
  public static final String parseDateyyyyMMdd(LocalDate localDate) {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
    return NDateu.parseLocalDate(formatter, localDate);
  }

  /**
   * 返回格式:yyyyMMddHH.
   */
  public static final String parseDateyyyyMMddHH(LocalDateTime localDateTime) {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHH");
    return NDateu.parseLocalDateTime(formatter, localDateTime);
  }

  /**
   * 返回格式:yyyyMMddHHmmss.
   */
  public static final String parseDateyyyyMMddHHmmss2(LocalDateTime localDateTime) {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
    return NDateu.parseLocalDateTime(formatter, localDateTime);
  }

  /**
   * 返回格式:yyyyMMddHHmm.
   */
  public static final String parseDateyyyyMMddHHmm3(LocalDateTime localDateTime) {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
    return NDateu.parseLocalDateTime(formatter, localDateTime);
  }

  /**
   * 返回格式:MMddHHmmss.
   */
  public static final String parseDateMMddHHmmss(LocalDateTime localDateTime) {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMddHHmmss");
    return NDateu.parseLocalDateTime(formatter, localDateTime);
  }

  /**
   * 返回格式:HH:mm:ss.
   */
  public static final String parseHHmmss(LocalTime localTime) {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
    return NDateu.parseLocalTime(formatter, localTime);
  }

  /**
   * 返回格式: HH:mm:ss.ms.
   */
  public static final String parseHHmmssms(LocalTime localTime) {
    long ms = localTime.getNano() / 1000000;
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
    return NDateu.parseLocalTime(formatter, localTime) + "." + (ms > 99 ? ms
        : (ms > 9 ? ("0" + ms) : ("00" + ms)));
  }

  /**
   * 返回格式:yyyy-MM-dd HH:mm:ss.ms.
   */
  public static final String parseDateyyyyMMddHHmmssms(LocalDateTime localDateTime) {
    long ms = localDateTime.getNano() / 1000000;
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    return NDateu.parseLocalDateTime(formatter, localDateTime) + "."
        + (ms > 99 ? ms : (ms > 9 ? ("0" + ms) : ("00" + ms)));
  }

  /**
   * 返回格式:yyyyMMddHHmmss.ms.
   */
  public static final String parseDateyyyyMMddHHmmssms2(LocalDateTime localDateTime) {
    long ms = localDateTime.getNano() / 1000000;
    return NDateu.parseDateyyyyMMddHHmm3(localDateTime) + "."
        + (ms > 99 ? ms : (ms > 9 ? ("0" + ms) : ("00" + ms)));
  }

  /**
   * 置为凌晨00:00:00 000.
   */
  public static final LocalDateTime set000000(LocalDateTime localDateTime) {
    LocalDateTime dateTime = LocalDateTime.of(localDateTime.getYear(), localDateTime.getMonth(),
        localDateTime.getDayOfMonth(), 0, 0, 0);
    return dateTime;
  }

  /**
   * 当前时间的hour, 小于10时前面补零.
   */
  public static final String hour(LocalTime localTime) {
    int hour = localTime.getHour();
    return hour > 9 ? hour + "" : "0" + hour;
  }

  /**
   * yyyymmdd整数形式.
   */
  public static final int yyyymmdd(LocalDate localDate) {
    return Integer
        .parseInt(localDate.getYear() + "" + localDate.getMonth() + "" + localDate.getDayOfMonth());
  }

  /**
   * yyyymm整数形式.
   */
  public static final int yyyymm(LocalDate date) {
    return Integer.parseInt(date.getYear() + "" + date.getMonth());
  }

  public static final String parseLocalDate(DateTimeFormatter formatter, LocalDate localDate) {
    try {
      return localDate == null ? null : localDate.format(formatter);
    } catch (Exception e) {
      return null;
    }
  }

  public static final String parseLocalTime(DateTimeFormatter formatter, LocalTime localTime) {
    try {
      return localTime == null ? null : localTime.format(formatter);
    } catch (Exception e) {
      return null;
    }
  }

  public static final String parseLocalDateTime(DateTimeFormatter formatter,
      LocalDateTime localDateTime) {
    try {
      return localDateTime == null ? null : localDateTime.format(formatter);
    } catch (Exception e) {
      return null;
    }
  }
}

他们还有很多方法,可以直接参考java API直接使用。

总结:
Java8已经推出来几年了,大部分公司都已经使用上了Java8,但是不一定每个人都特别习惯使用这些新特性,但是当你使用了,就一定会爱上这些。在多找一些资料,然后在自己的项目总使用这些吧!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值