首页 / JAVA / 26.java8新特性
26.java8新特性
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了26.java8新特性,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含23193字,纯文字阅读大概需要34分钟。
内容图文
![26.java8新特性](/upload/InfoBanner/zyjiaocheng/737/11ef753506f741109969a0091c1938f4.jpg)
Java8
? Java 8 (又称为 jdk 1.8) 是 Java 语言开发的一个主要版本。 Oracle 公司于 2014 年 3 月 18 日发布 Java 8 ,它支持函数式编程,新的 JavaScript 引擎,新的日期 API,新的Stream API 等。
- Lambda 表达式 ? Lambda允许把函数作为一个方法的参数(函数作为参数传递进方法中)。
- 方法引用 ? 方法引用提供了非常有用的语法,可以直接引用已有Java类或对象(实例)的方法或构造器。与lambda联合使用,方法引用可以使语言的构造更紧凑简洁,减少冗余代码。
- 默认方法 ? 默认方法就是一个在接口里面有了一个实现的方法。
- Stream API ?新添加的Stream API(java.util.stream) 把真正的函数式编程风格引入到Java中。
- Date Time API ? 加强对日期与时间的处理。
- Optional 类 ? Optional 类已经成为 Java 8 类库的一部分,用来解决空指针异常。
- Nashorn, JavaScript 引擎 ? Java 8提供了一个新的Nashorn javascript引擎,它允许我们在JVM上运行特定的javascript应用。
其中核心:Lambda表达式和Stream API
第一节:Lambda表达式
? Lambda表达式可以看成是匿名内部类,Lambda 允许把函数作为一个方法的参数(函数作为方法参数传递),将代码像数据一样传递,使用 Lambda 表达式可以使代码变的更加简洁紧凑。
? Lambda表达需要函数式接口的支持。
? 基本语法:
<函数式接口> <变量名> = (参数1,参数2...) -> {
//方法体
};
注意其中的参数1,参数2是接口中抽象方法的参数,如果方法的参数为空,则使用(),如果仅含有一个参数则可以省略()直接使用e->{},如果方法体内仅含有一条语句,那么可以省略大括号,如果带返回值且仅含有一条语句,则省略return语句和大括号。
实际上该式子相当于创建一个匿名内部类对象,该匿名内部类实现了接口的方法,并让变量名去引用该对象。
案例1:
1.1为什么使用lambda表达式
问题:如果再添加类似需求,需要再添加一个方法。如何解决?
2:使用Lambada表达式优化策略模式。
public static void main(String[] args) {
List<Employee> employees=new ArrayList<>();
employees.add(new Employee("xxx", 30, 10000));
employees.add(new Employee("yyy", 29, 8000));
employees.add(new Employee("zzz", 22, 12000));
employees.add(new Employee("张三", 21, 20000));
employees.add(new Employee("李四", 32, 22000));
//按照年龄过滤
System.out.println("-------------按照年龄过滤--------------");
List<Employee> list=filterEmployee(employees,(e)->e.getAge()>=25);
for (Employee employee : list) {
System.out.println(employee.toString());
}
System.out.println("-------------按照工资过滤--------------");
//按照工资过滤
List<Employee> list2=filterEmployee(employees,(e)->e.getSalary()>=10000);
for (Employee employee : list2) {
System.out.println(employee.toString());
}
}
public static List<Employee> filterEmployee(List<Employee> employees,MyPredicate<Employee> predicate) {
List<Employee> list=new ArrayList<>();
for (Employee e : employees) {
if(predicate.test(e)) {
list.add(e);
}
}
return list;
}
3:使用Stream API再优化lambda表达式
public static void main(String[] args) {
List<Employee> employees = new ArrayList<>();
employees.add(new Employee("xxx", 30, 10000));
employees.add(new Employee("yyy", 29, 8000));
employees.add(new Employee("zzz", 22, 12000));
employees.add(new Employee("张三", 21, 20000));
employees.add(new Employee("李四", 32, 22000));
// 按照年龄过滤
System.out.println("-------------按照年龄过滤--------------");
employees
.stream()
.filter((e) -> e.getAge() >= 25)
.forEach(System.out::println);
// 按照工资过滤
System.out.println("-------------按照工资过滤--------------");
employees
.stream()
.filter((e) -> e.getSalary() >= 10000)
.forEach(System.out::println);
}
1.2使用lambda表达式注意事项
Lambda引入了新的操作符:->(箭头操作符),->将表达式分成两部分
左侧:(参数1,参数2…)表示参数列表;
右侧:{}内部是方法体
1、形参列表的数据类型会自动推断;
2、如果形参列表为空,只需保留();
3、如果形参只有1个,()可以省略,只需要参数的名称即可;
4、如果执行语句只有1句,且无返回值,{}可以省略,若有返回值,则若想省去{},则必须同时省略return,且执行语句也保证只有1句;
5、lambda不会生成一个单独的内部类文件;
6、lambda表达式若访问了局部变量,则局部变量必须是final的,若是局部变量没有加final关键字,系统会自动添加,此后在修改该局部变量,会报错。
上机练习:
需求1:使用Collections.sort()方法,通过定制排序比较两个Employee(先按年龄比,年龄相同按姓名比),使用Lambda作为参数传递。
需求2:声明函数式接口,接口中声明抽象方法,public String getValue(String s);
编写测试类,类中编写方法使用接口作为参数,将一个字符串转成大写,并作为方法的返回值。
1.3函数式接口
? 如果一个接口只有一个抽象方法,则该接口称之为函数式接口,函数式接口可以使用Lambda表达式,lambda表达式会被匹配到这个抽象方法上 。
? 为了确保你的接口一定达到这个要求,你只需要给你的接口添加 @FunctionalInterface 注解,编译器如果发现你标注了这个注解的接口有多于一个抽象方法的时候会报错的。
@FunctionalInterface
interface Converter<F, T> {
T convert(F from);
}
Converter<String, Integer> converter = (from) -> Integer.valueOf(from);
Integer converted = converter.convert("123");
System.out.println(converted); // 123
? Java为了程序员方便使用Lambda表达式,Java内置了四个核心函数式接口
函数式接口 | 参数类型 | 返回类型 | 说明 |
---|---|---|---|
Consumer 消费型接口 | T | void | void accept(T t);对类型为T的对象应用操作 |
Supplier 供给型接口 | 无 | T | T get(); 返回类型为T的对象 |
Function<T,R> 函数型接口 | T | R | R apply(T t);对类型为T的对象应用操作,并返回类型为R类型的对象。 |
Predicate 断言型接口 | T | boolean | boolean test(T t);确定类型为T的对象是否满足条件,并返回boolean类型。 |
E、T、K、V、R
package com.qf.day15_4;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
public class Test {
public static void main(String[] args) {
happy(1000,(m)->System.out.println("吃烤全羊,消费"+m));
happy(10000,(m)->System.out.println("旅游消费"+m));
List<Integer> numbers = getNumbers(10, ()->new Random().nextInt(100));
for (Integer n : numbers) {
System.out.println(n);
}
System.out.println(stringOpe("hello", (s)->s.toUpperCase()));
System.out.println(stringOpe(" hello ", (s)->s.trim()));
List<String> names=new ArrayList<>();
names.add("张三");
names.add("张三丰");
names.add("张无忌");
names.add("李四");
names.add("王五");
List<String> names2=filterString(names,s->s.startsWith("张"));
for (String string : names2) {
System.out.println(string);
}
}
//消费型接口
public static void happy(double money,Consumer<Double> consumer) {
consumer.accept(money);
}
//供给型接口
public static List<Integer> getNumbers(int count,Supplier<Integer> supplier) {
List<Integer> numbers=new ArrayList<>();
for(int i=0;i<count;i++) {
numbers.add(supplier.get());
}
return numbers;
}
//函数型接口
public static String stringOpe(String s,Function<String, String> fun) {
return fun.apply(s);
}
//断言型接口
public static List<String> filterString(List<String> list,Predicate<String> p) {
List<String> list2=new ArrayList<>();
for (String string : list) {
if(p.test(string)) {
list2.add(string);
}
}
return list2;
}
}
第二节:方法引用
? 方法引用是lambda表达式的一种简写形式。 如果lambda表达式方法体中只是调用一个特定的已经存在的方法,则可以使用方法引用。
使用“::”操作符将方法名和对象或类的名字分隔开来。以下是四种使用情况:
- 对象::实例方法
- 类::静态方法
- 类::实例方法
- 类::new
package com.qf.day15_4;
import java.util.Comparator;
import java.util.TreeSet;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Supplier;
import com.qf.day15_3.Employee;
public class Test2 {
public static void main(String[] args) {
//1方法引用 对象::方法名
Consumer<String> con=(s)->System.out.println(s);
//等价于
Consumer<String> con2=System.out::println;
con.accept("hello");
con2.accept("world");
Employee e=new Employee("张亮", 20, 10000);
Supplier<String> sup=()->e.getName();
//等价于
Supplier<String> sup2=e::getName;
System.out.println(sup2.get());
//2方法引用 类名::静态方法
//Comparator<Integer> comparator=(x,y)->Integer.compare(x, y);
//等价于
Comparator<Integer> comparator=Integer::compare;
TreeSet<Integer> treeSet=new TreeSet<>(comparator);
//3方法引用: 类名::实例方法名
BiPredicate<String, String> bpre=(x,y)->x.equals(y);
BiPredicate<String, String> bpre2=String::equals;
Function<Employee,String> function=e->e.getName();
Function<Employee,String> function2=Employee::getName;
String name = function2.apply(shaobo);
System.out.println(name);
//4构造方法引用:
Supplier<Employee> sup3=()->new Employee();
//等价于
Supplier<Employee> sup4=Employee::new;//默认构造方法
}
}
第三节:Stream API
? Stream是Java8中处理数组、集合的抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API对集合数据进行操作,就类似于使用SQL执行的数据库查询。也可以使用Stream API来并行执行操作。
? 简单应用:统计一个字符串类型集合中,所有长度大于3的元素个数。
public static void main(String[] args) {
//传统实现
List<String> data=new ArrayList<>();
data.add("hello");
data.add("world");
data.add("ni");
data.add("apple");
data.add("china");
int count = 0;
for (String s : data) {
if (s.length() > 3)
count++;
}
System.out.println(count);
//Stream API
long count2= data
.stream()
.filter(s->s.length()>3)
.count();
System.out.println(count2);
}
上面代码中stream方法会为字符串列表生成一个Stream。filter方法会返回只包含字符串长度大于3的一个Stream,然后通过count方法计数。
3.1 什么是Stream?
? 一个Stream表面上与一个集合很类似,集合中保存的是数据,而流中对数据的操作。
注意:
特点:
Stream 自己不会存储元素。
Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream。
Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。
Stream遵循“做什么,而不是怎么去做”的原则。只需要描述需要做什么,而不用考虑程序是怎样实现的。
3.2 如何使用Stream API
使用Stream,会有三个阶段(步骤):
- 创建一个Stream。 (创建)
- 在一个或多个步骤中,将初始Stream转化到另一个Stream的中间操作。 (中间操作)
- 使用一个终止操作来产生一个结果。该操作会强制他之前的延迟操作立即执行。在这之后,该Stream就不会在被使用了。(终止操作)
3.2.1 Stream的创建方法
// 1. Stream.of方法
Stream stream = Stream.of("a", "b", "c");
// 2. Arrays.of方法
String [] strArray = new String[] {"a", "b", "c"};
stream = Stream.of(strArray);
stream = Arrays.stream(strArray);
// 3. 集合方法
List<String> list = Arrays.asList(strArray);
stream = list.stream();
stream = list.parallelStream();//并行流
//4.创建无限流
//迭代
Stream<Integer> stream = Stream.iterate(0, (x)->x+2);
stream.limit(10)
.forEach(System.out::println);
//生成
Stream<Double> stream2 = Stream.generate(()->Math.random());
stream2.limit(5)
.forEach(System.out::println);
3.2.2 Stream中间操作
中间操作包括:map (mapToInt, flatMap 等)、 filter、distinct、sorted、peek、limit、skip、parallel、sequential、unordered。
? 多个中间操作可以连接起来形成一个流水线,除非流水 线上触发终止操作,否则中间操作不会执行任何的处理! 而在终止操作时一次性全部处理,称为“惰性求值”。
筛选和切片
public static void main(String[] args) {
List<Employee> employees=new ArrayList<>();
employees.add(new Employee("xxx", 30, 10000));
employees.add(new Employee("yyy", 29, 8000));
employees.add(new Employee("zzz", 22, 12000));
employees.add(new Employee("张三", 21, 20000));
employees.add(new Employee("李四", 32, 22000));
//employees.add(new Employee("李四", 32, 22000));
//1 筛选和切片
// filter---从流中排除元素
// limit——截断流,使其元素不超过给定数量。
// skip(n) —— 跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个,则返回一个空流。与 limit(n) 互补
// distinct——筛选,通过流所生成元素的 equals() 去除重复元素
System.out.println("-----------filter------------");
Stream<Employee> stream = employees.stream().filter((e)->e.getAge()>=25);
stream.forEach(System.out::println);
System.out.println("---------limit-------");
Stream<Employee> stream2 = employees.stream().limit(3);
stream2.forEach(System.out::println);
System.out.println("---------skip-------");
Stream<Employee> stream3= employees.stream().skip(2);
stream3.forEach(System.out::println);
System.out.println("---------distinct-------");//通过equals方法去重复
Stream<Employee> stream4= employees.stream().distinct();
stream4.forEach(System.out::println);
}
映射
public static void main(String[] args) {
List<Employee> employees = new ArrayList<>();
employees.add(new Employee("xxx", 30, 10000));
employees.add(new Employee("yyy", 29, 8000));
employees.add(new Employee("zzz", 22, 12000));
employees.add(new Employee("张三", 21, 20000));
employees.add(new Employee("李四", 32, 22000));
// map——接收 Lambda ,
// 将元素转换成其他形式或提取信息。接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
System.out.println("----------获取员工姓名-----------");
Stream<String> str = employees.stream().map((e) -> e.getName());
str.forEach(System.out::println);
System.out.println("-------------------转成大写------------------------");
List<String> strList = Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee");
Stream<String> stream = strList.stream().map(String::toUpperCase);
stream.forEach(System.out::println);
}
排序
public static void main(String[] args) {
List<Employee> employees = new ArrayList<>();
employees.add(new Employee("xxx", 30, 10000));
employees.add(new Employee("yyy", 29, 8000));
employees.add(new Employee("zzz", 22, 12000));
employees.add(new Employee("张三", 21, 20000));
employees.add(new Employee("李四", 32, 22000));
/*
sorted()——自然排序
sorted(Comparator com)——定制排序
*/
System.out.println("-----------------自然排序-------------------");
employees.stream().map(Employee::getName).sorted().forEach(System.out::println);
System.out.println("-----------------定制排序-------------------");
employees.stream().sorted((x, y) -> {
if (x.getAge() == y.getAge()) {
return x.getName().compareTo(y.getName());
} else {
return Integer.compare(x.getAge(), y.getAge());
}
}).forEach(System.out::println);
}
3.2.3 Stream 的终止操作
终止操作包括:forEach、forEachOrdered、toArray、reduce、collect、min、max、count、anyMatch、allMatch、noneMatch、findFirst、findAny、iterator。
遍历
forEach
查找和匹配
allMatch——检查是否匹配所有元素
anyMatch——检查是否至少匹配一个元素
noneMatch——检查是否没有匹配的元素
findFirst——返回第一个元素
findAny——返回当前流中的任意元素
count——返回流中元素的总个数
max——返回流中最大值
min——返回流中最小值
public static void main(String[] args) {
List<Employee> employees = new ArrayList<>();
employees.add(new Employee("xxx", 30,"男",10000));
employees.add(new Employee("yyy", 29,"男",8000));
employees.add(new Employee("zzz", 22, "男",12000));
employees.add(new Employee("张三", 21,"男",20000));
employees.add(new Employee("李四", 32,"男",22000));
//-----------foreach--------------
employees.stream().forEach(System.out::println);
/**
* allMatch——检查是否匹配所有元素
anyMatch——检查是否至少匹配一个元素
noneMatch——检查是否没有匹配的元素
findFirst——返回第一个元素
findAny——返回当前流中的任意元素
count——返回流中元素的总个数
max——返回流中最大值
min——返回流中最小值
*/
boolean b = employees.stream().allMatch((e)->e.getSex().equals("男"));
boolean b2 = employees.stream().anyMatch((e)->e.getSex().equals("女"));
boolean b3=employees.stream().noneMatch((e)->e.getSex().equals("女"));
System.out.println(b);
System.out.println(b2);
System.out.println(b3);
Optional<Employee> findFirst = employees.stream().findFirst();
System.out.println(findFirst.get());
Optional<Employee> findAny = employees.parallelStream().findAny();
System.out.println(findAny.get());
Optional<Employee> max = employees.stream().max((o1,o2)->o1.getAge()-o2.getAge());
System.out.println(max.get());
Optional<Double> min = employees.stream().map(Employee::getSalary).min(Double::compareTo);
System.out.println(min.get());
}
归约和收集
public static void main(String[] args) {
List<Employee> employees = new ArrayList<>();
employees.add(new Employee("xxx", 30, "男", 10000));
employees.add(new Employee("yyy", 29, "男", 8000));
employees.add(new Employee("zzz", 22, "男", 12000));
employees.add(new Employee("张三", 21, "男", 20000));
employees.add(new Employee("李四", 32, "男", 22000));
// -----------foreach--------------
employees.stream().forEach(System.out::println);
/**
* reduce归约 reduce(T identity, BinaryOperator) / reduce(BinaryOperator)
* ——可以将流中元素反复结合起来,得到一个值
*/
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Integer sum = list.stream().reduce(0, (x, y) -> x + y);
System.out.println(sum);
System.out.println("----------------------------------------");
Optional<Double> op = employees.stream().map(Employee::getSalary).reduce(Double::sum);
System.out.println(op.get());
/**
* collect——将流转换为其他形式。接收一个 Collector接口的实现,用于给Stream中元素做汇总的方法
*
*/
System.out.println("-------------List集合---------------------");
List<String> list2 = employees.stream().map(Employee::getName).collect(Collectors.toList());
list2.forEach(System.out::println);
System.out.println("---------------Set集合-------------------");
Set<String> set = employees.stream().map(Employee::getName).collect(Collectors.toSet());
set.forEach(System.out::println);
}
3.2.4 并行操作
Stream有串行和并行两种,串行Stream上的操作是在一个线程中依次完成,而并行Stream则是在多个线程上同时执行。
int max = 1000000;
List<String> values = new ArrayList<>(max);
for (int i = 0; i < max; i++) {
UUID uuid = UUID.randomUUID();
values.add(uuid.toString());
}
计算一下排序这个Stream要耗时多久:
public static void main(String[] args) {
int max = 1000000;
List<String> values = new ArrayList<>(max);
for (int i = 0; i < max; i++) {
UUID uuid = UUID.randomUUID();
values.add(uuid.toString());
}
System.out.println("----------串行------------");
long t0 = System.currentTimeMillis();
long count = values.stream().sorted().count();
System.out.println(count);
long t1 = System.currentTimeMillis();
long millis = t1-t0;
System.out.println(millis);
// System.out.println("-------------并行----------------");
// long t0 = System.currentTimeMillis();
// long count = values.parallelStream().sorted().count();
// System.out.println(count);
// long t1 = System.currentTimeMillis();
// long millis = t1-t0;
// System.out.println(millis);
}
第四节:新时间日期API
Java 8通过发布新的Date-Time API (JSR 310)来进一步加强对日期与时间的处理。
在旧版的 Java 中,日期时间 API 存在诸多问题,其中有:
- 非线程安全 ? java.util.Date 是非线程安全的,所有的日期类都是可变的,这是Java日期类最大的问题之一。
- 设计很差 ? Java的日期/时间类的定义并不一致,在java.util和java.sql的包中都有日期类,此外用于格式化和解析的类在java.text包中定义。java.util.Date同时包含日期和时间,而java.sql.Date仅包含日期,将其纳入java.sql包并不合理。另外这两个类都有相同的名字,这本身就是一个非常糟糕的设计。
- 时区处理麻烦 ? 日期类并不提供国际化,没有时区支持,因此Java引入了java.util.Calendar和java.util.TimeZone类,但他们同样存在上述所有的问题。
Java 8 在 java.time 包下提供了很多新的 API。以下为两个比较重要的 API:
- Local(本地) ? 简化了日期时间的处理,没有时区的问题。
- ZoneId (时区) ? 通过定制的时区处理日期时间。
线程安全问题演示:
public static void main(String[] args) throws Exception{
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
Callable<Date> task = new Callable<Date>() {
@Override
public Date call() throws Exception {
return sdf.parse("20161121");
}
};
ExecutorService pool = Executors.newFixedThreadPool(10);
List<Future<Date>> results = new ArrayList<>();
for (int i = 0; i < 10; i++) {
results.add(pool.submit(task));
}
for (Future<Date> future : results) {
System.out.println(future.get());
}
pool.shutdown();
}
使用新时间日期API解决
public static void main(String[] args) throws Exception{
DateTimeFormatter formatter=DateTimeFormatter.ofPattern("yyyyMMdd");
Callable<LocalDate> task = new Callable<LocalDate>() {
@Override
public LocalDate call() throws Exception {
return LocalDate.parse("20161002", formatter);
}
};
ExecutorService pool = Executors.newFixedThreadPool(10);
List<Future<LocalDate>> results = new ArrayList<>();
for (int i = 0; i < 10; i++) {
results.add(pool.submit(task));
}
for (Future<LocalDate> future : results) {
System.out.println(future.get());
}
pool.shutdown();
}
4.1 本地化日期时间 API
LocalDate/LocalTime 和 LocalDateTime 类可以在处理时区不是必须的情况。
LocalDate、LocalTime、LocalDateTime 类的实例是不可变的对象,分别表示使用 ISO-8601日 历系统的日期、时间 、日期和时间。它们提供了简单的日期或时间,不包含与时区相关的信息。
public static void main(String[] args) {
//当前时间
LocalDateTime ldt=LocalDateTime.now();
System.out.println(ldt);
//其他时间
LocalDateTime ldt2=LocalDateTime.of(2012, 10, 1, 10, 10,10);
System.out.println(ldt2);
//加时间
LocalDateTime ldt3=ldt2.plusDays(2);
System.out.println(ldt3);
//减时间
LocalDateTime ldt4 = ldt3.minusHours(2);
System.out.println(ldt4);
//获取时间部分
System.out.println(ldt.getYear());
System.out.println(ldt.getMonthValue());
System.out.println(ldt.getDayOfMonth());
System.out.println(ldt.getHour());
System.out.println(ldt.getMinute());
System.out.println(ldt.getSecond());
}
4.2 Instant、ZoneId
Instant 时间戳 类似以前的Date、Timestamp
? 它是以Unix元年(传统 的设定为UTC时区1970年1月1日午夜时分)开始 所经历的描述进行运算
ZoneId 时区
public static void main(String[] args) throws Exception {
//时间戳
Instant instant=Instant.now();
System.out.println(instant);
Thread.sleep(1000);
Instant instant2=Instant.now();
long millis = Duration.between(instant, instant2).toMillis();
System.out.println(millis);
//时区
System.out.println(ZoneId.getAvailableZoneIds());
ZoneId zone1 = ZoneId.of("Europe/Berlin");
ZoneId zone2 = ZoneId.of("Brazil/East");
System.out.println(zone1.getRules());
System.out.println(zone2.getRules());
//时间转换
//Date-----Instant-------LocalDateTime
System.out.println("--------Date-----Instant-------LocalDateTime---------");
Date date=new Date();
//把date转成instant
Instant instant1 = date.toInstant();
//intant转成LocalDateTime
LocalDateTime localDateTime = instant1.atZone(ZoneId.systemDefault()).toLocalDateTime();
System.out.println(localDateTime);
System.out.println("--------LocalDateTime-----Instant-------Date---------");
Instant instant3 = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
Date date2 = Date.from(instant3);
System.out.println(date2);
}
4.3 时间矫正器 TemporalAdjuster
TemporalAdjuster : 时间校正器。有时我们可能需要获 取例如:将日期调整到“下个周日”等操作。
TemporalAdjusters : 该类通过静态方法提供了大量的常 用 TemporalAdjuster 的实现。
例如获取下个周日:
LocalDate date=LocalDate.now();
//下一个周5
System.out.println(date.with(TemporalAdjusters.next(DayOfWeek.FRIDAY)));
//下一个周2
System.out.println(date.with(TemporalAdjusters.next(DayOfWeek.TUESDAY)));
//下一个周日(周日为每周的第一天)
System.out.println(date.with(TemporalAdjusters.next(DayOfWeek.SUNDAY)));
4.4 DateTimeFormatter
java.time.format.DateTimeFormatter 类:该类提供了三种 格式化方法:
? 预定义的标准格式
? 语言环境相关的格式
? 自定义的格式
DateTimeFormatter dtf = DateTimeFormatter.ISO_LOCAL_DATE;
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss E");
LocalDateTime ldt = LocalDateTime.now();
String strDate = ldt.format(dtf);
System.out.println(strDate);
LocalDateTime newLdt = ldt.parse(strDate, dtf);
System.out.println(newLdt);
总结:
1 Lambda表达式:把代码(方法)作为方法的参数传递。
操作符 ->
函数式接口:只有一个抽象方法的接口
Consumer 消费型接口 void accept(T)
Supplier 供给型接口 T get();
Function 函数型接口 R apply(T)
Predicate 断言性接口 boolean test(T)
2 方法引用:
? 对象::实例方法
? 类名::静态方法
? 类名::实例方法
? 类名::new
3 Stream API
? Stream: 包含了对集合或的数组的操作,延迟执行。调用终止方法,中间操作立即执行。
三步: (1) 创建流
? Stream.of();
? Arrays.stream();
? 集合.stream()
? .parallelStream();
? (2) 添加中间操作
? filter skip limit map sort
? (3) 终止操作
? foreach count max min allMatch anyMatch noneMatch findFirst findAny findLast … reduce collect
4 时间
? LocalDateTime
? Instant
? ZoneId
? Date和Instant Instant和LocalDateTime之间的转换
? 矫正器
? 时间格式化
? DateTimeFormatter
内容总结
以上是互联网集市为您收集整理的26.java8新特性全部内容,希望文章能够帮你解决26.java8新特性所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。