1.为什么要学习Java8中的新特性,在快速更新的年代,技术要想不被淘汰,就需要不断的更新知识,而Java8中需要新的特性,能够大大的简化编程。并且在项目中依旧使用Java6,Java7,这只能证明这整个开发团队学习态度有问题,不管是因为什么原因,如果仅仅是因为升级Java8有风险,而不去做的话,只能抱着陈旧的知识,被这个时代所淘汰。这里有一个观点,需要不断的更新,优化自己的项目,只有将这个项目朝着更好的方法做,这个项目才有价值,否则仅仅开发完了就扔掉的项目,那是没有任何价值,也不能给你带来新的知识,只是有熟悉了一遍以前做过的事情,不能使自己成长。接下来聊一下Java需要理解的特性:
2.需要知道Java8新特性:
首先一个例子
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.仅一次使用,后续无法再次使用该流。可以比作成一条操作流水线,最后消费掉之后,不无法在此使用。
2.内部采用迭代的方式。
流的操作分为中间操作和终端操作,中间操作是对流的处理,终端操作是获取流的结果。
Stream of = Stream.of("Java","Spring"); //通过值创建流
Stream of = Arrays.stream({1,2,3});//通过数组创建流
Stream stream = list.stream(); //通过集合创建流
Stream 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 |
方法的引用分三种:
List users = list.stream().filter(user->user.getAge()>18).collect(Collectors.toList());
List names = list.stream().map(user->user.getName()).collect(Collectors.toList());
List users = list.stream().distinct().collect(Collectors.toList());
List users = list.stream().skip(10).limit(5).collect(Collectors.toList());
list.stream().flatMap(user.stream).collect(Collectors.toList());
list.stream().map(user->user.getName()).sort().collect(Collectors.toList()); //sort()使用自然排序
list.stream().sorted(Comparator.comparing(Student::getAge)) ;// age从小到到排序
终端操作就是一个类似收集器一样,在经过前面的一系列的操作之后,将流生成一个可以操作的集合或者是数据。
list.stream().collect(Collectors.toList());// 流转变为list集合
list.stream().count; //获取流中的个数
//获取年龄最大的用户,User::getAge,方法的引用可以写成该样式,如果需要使用
Comparator comparator = Comparator.comparingInt(User::getAge);
Optional maxUser = list.stream().collect(maxBy(comparator));
//获取年龄最小的用户
Comparator comparator = Comparator.comparingInt(User::getAge);
Optional 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>maps = list.stream.collect(groupingBy(User::getName)); //以姓名进行分组
Mapmaps = list.stream.collect(groupingBy(User::getName,counting())); //以姓名进行分组,并计算每个组汇中的个数,二级分组,即在分组之后对集合进行操作。
小结:流的操作能够能够极大的简化代码,对于之后集合中for if的操作,stream的操作完全可以进行替代。一行代码能够解决,使得代码更简洁更容易读懂。
在使用到接口的使用,都需要实现一下接口的方法(特指只有一个方法的接口)例如:
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Hello World!");
}
});
该代码紧紧只输出一行代码,但是其他代码都是废话,在实际上都不需要,lambda就能够简化
new Thread(() ->System.out.println("Hello World!") );
为什么能够这样写 ,首先我只关心传入的参数,如果没有参数,那么其实都不需要关心接口的名词是是什么,可以看下一个:
Comparator comparator= new Comparator(){
public int compare(User a1,User a2){
return a1.getAge().compareTo(a2.getAge());
}
}
转化为lambda表达式:
Comparator comparator = (User a1,User a2) -> a1.getAge().compareTo(a2.getAge());
这个时候代码看起来简洁了,同时也因为Java有类型推断,不用关心User,更洁净的方式:
Comparator comparator = (a1,a2) -> a1.getAge().compareTo(a2.getAge());
通过上面两个例子,自己可以构建一个方法,而只要这个接口只有一个方法,那么就能够在使用过程中使用Lambda。
Java内置了一些有用的Lambda表达式,但常用的有两个:
Comsumer T -> void
Function
lambda表达式其实是一个方法,既然是方法,就需要去有人调用,在一个地方new出该表达式,在需要的地方消费。
List> list = new ArrayList<>(); //Consumer中Void为空,标识什么都不传
list.add(v-> System.out.println("hello world!"));
for(Consumer v: list){
v.accept(null); //将lambda消费掉,需要捕获异常
}
先产生lambda表达式,然后进行消费掉,这里仅仅只是演示了lambda中Consumer的使用,而这一使用极大的改变了写代码的思路,不在需要写一个接口。
为什么要使用Java8增强的时间类,第一java.util.Date是可变类型,SimpleDateFormat是非线程安全的。并且操作起来麻烦。
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,但是不一定每个人都特别习惯使用这些新特性,但是当你使用了,就一定会爱上这些。在多找一些资料,然后在自己的项目总使用这些吧!