目录

  • 一、Lambda

    • 1、定义/设计原因
    • 2、结构
    • 3、规则
    • 4、使用
  • 二、函数式接口
    • 1、定义
    • 2、设计原因
    • 3、使用
  • 三、方法引用
    • 1、定义/设计原因
    • 2、使用
  • 四、接口的默认方法
    • 1、定义
    • 2、设计原因
    • 3、使用
  • 五、Stream
    • 1、定义
    • 2、设计原因
    • 2、使用
  • 六、Optional 类
    • 1、定义
    • 2、设计原因
    • 3、使用
  • 六、日期时间类
    • 1、定义
    • 2、设计原因
    • 3、使用
  • 七、Base64
    • 1、定义
    • 2、使用

一、Lambda

1、定义/设计原因

官方解释:允许把函数作为一个方法的参数。使代码变的更加简洁紧凑。表达式免去了使用匿名方法的麻烦。
个人解释:用来创建匿名方法

2、结构

Lambda表达式可由逗号分隔的参数列表、->符号和语句块组成

  • 可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
  • 可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
  • 可选的大括号:如果主体只有一个语句,就不需要使用大括号。
  • 可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号必须指定return值

3、规则

表达式用到的局部变量不管是不是final,都会被变成final,后面代码不可以改它了。全局变量则不受限。

4、使用


public class Java8Tester {@FunctionalInterfaceinterface MathOperation {int operation(int a, int b);}@FunctionalInterfaceinterface GreetingService {void sayMessage(String message);}public static void main(String args[]){//老版本写法MathOperation oldAdd = new MathOperation() {@Overridepublic int operation(int a, int b) {return a+b;}};// jdk8类型声明MathOperation addition = (int a, int b) -> a + b;// 不用类型声明MathOperation subtraction = (a, b) -> a - b;// 大括号中的返回语句MathOperation multiplication = (int a, int b) -> { return a * b; };// 没有大括号及返回语句MathOperation division = (int a, int b) -> a / b;// 不用括号GreetingService greetService1 = message ->System.out.println("Hello " + message);// 用括号GreetingService greetService2 = (message) ->System.out.println("Hello " + message);greetService1.sayMessage("Runoob");greetService2.sayMessage("Google");}}

二、函数式接口

1、定义

官方解释:函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。函数式接口可以被隐式转换为 lambda 表达式和方法引用。
@FunctionalInterface,用于编译级错误检查,加上该注解,当你写的接口不符合函数式接口定义的时候,编译器会报错。

2、设计原因

lambda语法只能用函数式接口,为方便检查函数式接口,给了这个@FunctionalInterface注解

3、使用

@FunctionalInterfaceinterface
GreetingService {void sayMessage(String message);
}
//使用Lambda表达式来表示该接口的一个实现
GreetingService greetService1 = message -> System.out.println("Hello " + message);

三、方法引用

1、定义/设计原因

官方解释:通过方法的名字来指向一个方法。可以使语言的构造更紧凑简洁,减少冗余代码。
个人解释:方法引用是一种更简洁易懂的Lambda表达式。直接访问类或者实例的方法或者构造方法。

2、使用

先创建个接口和类

 //函数式接口
@FunctionalInterface
public interface Supplier<T> {T get();
}class Car {public static Car create(final Supplier<Car> supplier) {return supplier.get();}public static void collide(final Car car) {System.out.println("Collided " + car.toString());}public void repair() {System.out.println("Repaired " + this.toString());}
}

开始使用方法引用:

   @Testpublic void MethodReferenceTest() {
//        1、旧方法写法
//        final Car oldCar = Car.create(new Supplier<Car>() {
//            @Override
//            public Car get() {
//                return new Car();
//            }
//        });
//        2、jdk8的lambda
//        final Car oldCar1 = Car.create(() -> new Car());//3、jdk8写法//构造器引用  Class::newfinal Car newCar = Car.create(Car::new);//该方法返回的 List 与传入数组是映射关系(视图):set/get 操作直接作用于数组;直接修改数组,list 也会改变final List<Car> cars = Arrays.asList(newCar);
/*-----------------------------分割线---------------------------------------*///       1、旧方法写法
//        for (Car car : cars) {
//            Car.collide(car);
//        }
//        2、jdk8的forEach
//        cars.forEach(new Consumer<Car>() {
//            @Override
//            public void accept(Car car) {
//                Car.collide(car);
//            }
//        });
//        3、jdk8的lambda
//        cars.forEach(car -> Car.collide(car));//4、jdk8方法引用写法//类名的方法引用 Class::static_method 或者 Class::methodcars.forEach(Car::collide);
/*-----------------------------分割线----------------------------------------*/final Car police = Car.create(Car::new);//       1、jdk8的lambda
//        cars.forEach(car -> police.follow(car));//2、jdk8方法引用写法//特定对象的方法引用  instance::methodcars.forEach(police::follow);}/*-----------------------------分割线---------------------------------------*/String[] stringsArray= {"4","5"};
//       1、旧方法写法
//        Arrays.sort(stringsArray, new Comparator<String>() {
//            @Override
//            public int compare(String s1, String s2) {
//                return s1.compareToIgnoreCase(s2);
//            }
//        });
//        2、jdk8的lambda
//        Arrays.sort(stringsArray,(s1,s2)->s1.compareToIgnoreCase(s2));//3、jdk8的方法引用Arrays.sort(stringsArray, String::compareToIgnoreCase);

四、接口的默认方法

1、定义

官方解释:默认方法就是接口可以有实现方法,而且不需要实现类去实现其方法。我们只需在方法名前面加个 default 关键字即可实现默认方法。

2、设计原因

问:为什么要有这个特性?
答:首先,之前的接口是个双刃剑,好处是面向抽象而不是面向具体编程,缺陷是,当需要修改接口时候,需要修改全部实现该接口的类,通常能想到的解决办法是在JDK里给相关的接口添加新的方法及实现。然而,对于已经发布的版本,是没法在给接口添加新方法的同时不影响已有的实现。所以引进的默认方法。他们的目的是为了解决接口的修改与现有的实现不兼容的问题。

3、使用

(1)接口的默认方法
最基本使用,接口通过default定义默认方法,实现类无需实现该方法

interface Vehicle {default void print() {System.out.println("我是一辆车!");}
}class Car implements Vehicle{}

如果一个类实现了多个接口,且这些接口有相同的默认方法,则可以通过
重写接口的默认方法,或者使用 super 来调用指定接口的默认方法

public interface Vehicle {default void print(){System.out.println("我是一辆车!");}
}
public interface FourWheeler {default void print(){System.out.println("我是一辆四轮车!");}
}
//创建自己的默认方法,来覆盖重写接口的默认方法
public class Car implements Vehicle, FourWheeler {default void print(){System.out.println("我是一辆四轮汽车!");}
}
//使用 super 来调用指定接口的默认方法
public class Car implements Vehicle, FourWheeler {public void print(){Vehicle.super.print();}
}

(2)接口的静态默认方法
不实例化接口的时候也可以用,个人感觉失去了接口的本质,但是妥协旧代码是这样的啦

public interface Animal {static void putUpHands(){System.out.println("举手");}
}class Cat {void catPutUpHands(){Animal.putUpHands();}
}

五、Stream

1、定义

官方解释:让你以一种声明的方式处理数据。将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。元素流在管道中经过中间操作的处理,最后由最终操作得到前面处理的结果。Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。
个人解释:把数组通过.stream()或者.parallelStream()转换成流,然后通过filter、map、distinct、sorted、limit等方法进行中间处理,最后通过collect、forEach、count得出最终结果。

2、设计原因

简化数组处理

2、使用

public static void main(String[] args) {List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd", "", "jkl");List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5, 1, 9, 10, 4, 1);/*=======================返回Stream<T>==========================*///1、filter过滤strings.stream().filter(string -> !string.isEmpty());//2、map映射每个元素到对应的结果numbers.stream().map(i -> i * i);//3、distinct去重numbers.stream().distinct();//4、sorted排序numbers.stream().sorted();//4、limit限制数量numbers.stream().limit(5);//5、并行处理,主要适用于大数据量的数组strings.parallelStream();/*=======================对流进行转换或处理的==========================*///1、collect转换成列表或字符串,Collectors 可将流转换成集合和聚合元素List<String> collect = strings.stream().collect(Collectors.toList());String collectStr = strings.stream().collect(Collectors.joining(", "));//2、forEach迭代流中的每个数据strings.stream().forEach(System.out::println);//3、count统计数量long count = strings.stream().count();/*=======================拓展IntStream,LongStream,DoubleStream==========================*///1.1、mapToInt将Stream转换成IntStream, summaryStatistics是对IntStream数据进行汇总统计的方法,(LongStream,DoubleStream同理)IntSummaryStatistics summary = numbers.stream().mapToInt(x ->x).summaryStatistics();System.out.println(summary.getAverage());System.out.println(summary.getCount());System.out.println(summary.getMax());System.out.println(summary.getMin());System.out.println(summary.getSum());//1.2、IntStream,LongStream创建区间方式是一样的int[] range1 = IntStream.rangeClosed(13, 15).toArray();//生产区间 [a,b]      range1=[13,14,15]int[] range2 = IntStream.range(13, 15).toArray();//生产区间 [a,b)     range2=[13,14]double[] doubles = DoubleStream.of(5.33, 2.34, 5.32, 2.31, 3.51).toArray(); //doubles=[5.33, 2.34, 5.32, 2.31, 3.51]//1.2、IntStream的统计方法(LongStream,DoubleStream同理)double average = IntStream.range(13, 15).average().getAsDouble();//average=13.5int max = IntStream.range(13, 15).max().getAsInt(); //max=14int min = IntStream.range(13, 15).min().getAsInt(); //min=13int sum = IntStream.range(13, 15).sum(); //sum=27}

六、Optional 类

1、定义

官方解释:Optional 类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。Optional 是个容器:它可以保存类型T的值,或者仅仅保存null。

个人解释:换言之就是把变量转成Optional对象,其中null都转成Optional.empty()(就是一个空的Optional对象),然后就可以对Optional对象进行操作。好处就是发现null可选择抛出异常。

2、设计原因

不用显式进行空值检测。解决空指针异常。避免null。

3、使用

public class OptionalTest {public static void main(String args[]){handleParam(null,1);//后面两个参数自己随意写}//处理参数举例子static void handleParam(String a,Integer b){//对于处理string参数Optional<String> aOpt = Optional.ofNullable(a); //允许参数空。如果非空返回一个包含引用Optional实例,否则返回Optional.empty()。System.out.println(aOpt.isPresent());//输出aOpt是否为空a=aOpt.orElse("defaultValue");//如果为空,就给一个默认值defaultValueSystem.out.println(a);//同理对于处理int参数Optional<Integer> bOpt = Optional.of(b);//不允许参数空,不然会抛出异常b=bOpt.get();//get的时候不允许变量为空System.out.println(b);}
}

六、日期时间类

1、定义

加强对日期与时间的处理。

2、设计原因

在旧版的 Java 中,日期时间 API 存在诸多问题

  • (1)非线程安全 − java.util.Date 是非线程安全的,所有的日期类都是可变的,这是Java日期类最大的问题之一。
  • (2)设计很差 − Java的日期/时间类的定义并不一致,在java.util和java.sql的包中都有日期类,此外用于格式化和解析的类在java.text包中定义。
    java.util.Date同时包含日期和时间,而java.sql.Date仅包含日期,将其纳入java.sql包并不合理。另外这两个类都有相同的名字,这本身就是一个非常糟糕的设计。
  • (3)时区处理麻烦 − 日期类并不提供国际化,没有时区支持,因此Java引入了java.util.Calendar和java.util.TimeZone类,但他们同样存在上述所有的问题。

3、使用

 public static void testTime() {// 当前详细时间LocalDateTime currentTime = LocalDateTime.now(); //currentTime =  2019-05-30T15:05:46.408// 当前年月日LocalDate date1 = currentTime.toLocalDate(); //date1 = 2019-05-30//获取详细时间的月日秒Month month = currentTime.getMonth();//month=MAYint day = currentTime.getDayOfMonth();//day=30int seconds = currentTime.getSecond();//seconds=46//替换详细时间的年月LocalDateTime date2 = currentTime.withDayOfMonth(10).withYear(2012);//date2 = 2012-05-10T15:05:46.408//自定义年月日LocalDate date3 = LocalDate.of(2014, Month.DECEMBER, 12);//date3= 2014-12-12//自定义时分LocalTime date4 = LocalTime.of(22, 15); //date4 = 22:15//解析字符串LocalTime date5 = LocalTime.parse("20:15:30"); //date5 = 20:15:30LocalDateTime date6 = LocalDateTime.parse("2019-05-30T15:05:46.408");//date6 = 2019-05-30T15:05:46.408// 获取当前时间日期ZonedDateTime date7 = ZonedDateTime.parse("2015-12-03T10:15:30+05:30[Asia/Shanghai]");//date6=2015-12-03T10:15:30+08:00[Asia/Shanghai]// 获取时区IDZoneId id = ZoneId.of("Europe/Paris");//id= Europe/Paris//获取默认时区ZoneId defaultZone = ZoneId.systemDefault();//defaultZone=sia/Shanghai}

七、Base64

1、定义

官方解释:Base64工具类提供了一套静态方法获取下面三种BASE64编码器和解码器:

  • 基本:输出被映射到一组字符A-Za-z0-9+/,编码不添加任何行标,输出的解码仅支持A-Za-z0-9+/。
  • URL:输出映射到一组字符A-Za-z0-9+_,输出是URL和文件。
  • MIME:输出隐射到MIME友好格式。输出每行不超过76字符,并且使用'\r'并跟随'\n'作为分割。编码输出最后没有行分割。

2、使用

public static void main(String args[]) {try {// 使用基本编码String base64encodedString = Base64.getEncoder().encodeToString("我是测试字符串".getBytes("utf-8"));//base64encodedString = "5oiR5piv5rWL6K+V5a2X56ym5Liy"// 解码byte[] base64decodedBytes = Base64.getDecoder().decode(base64encodedString);String base64decodedStr= new String(base64decodedBytes, "utf-8");//base64decodedStr = "我是测试字符串"//使用URL编码String urlEncodedString = Base64.getUrlEncoder().encodeToString("testUrl?java8".getBytes("utf-8"));//urlEncodedString = "VHV0b3JpYWxzUG9pbnQ_amF2YTg="//使用MIME编码String mimeEncodedString = Base64.getMimeEncoder().encodeToString(("QWERTYUIOP-ASDFGHJKL-ZXCVBNM").getBytes("utf-8"));//mimeEncodedString = "UVdFUlRZVUlPUC1BU0RGR0hKS0wtWlhDVkJOTQ=="}catch(UnsupportedEncodingException e){System.out.println("Error :" + e.getMessage());}}

转载于:https://www.cnblogs.com/ranandrun/p/java8.html

浓缩版java8新特性相关推荐

  1. java8新特性_Java8新特性之Date API|乐字节

    大家好,我是乐字节的小乐,上篇文章讲述了<Java8新特性之Optional>,接下来,小乐将接着讲述Java8新特性之Date API 2019日历 Java8之Date API Jav ...

  2. java8新特性_乐字节-Java8新特性-接口默认方法

    总概 JAVA8 已经发布很久,而且毫无疑问,java8是自java5(2004年发布)之后的最重要的版本.其中包括语言.编译器.库.工具和JVM等诸多方面的新特性. Java8 新特性列表如下: 接 ...

  3. java8新特性(6)— 日期与时间

    java8新特性(6)- 日期与时间 全新的日期与时间处理 package com.common.jdk8;import java.time.*;//Java 8通过发布新的Date-Time API ...

  4. Java8新特性学习_001_(Lambda表达式,函数式接口,方法引用,Stream类,Optional类)

    目录 ■代码 ■代码运行结果 ■代码说明 ・44行:Stream的.foreach方法ー参数类型:函数式接口 ・82行:Interface中,default方法 ・92行   Stream的.max方 ...

  5. 【小家java】java8新特性之---全新的日期、时间API(JSR 310规范),附SpringMVC、Mybatis中使用JSR310的正确姿势

    [小家java]java5新特性(简述十大新特性) 重要一跃 [小家java]java6新特性(简述十大新特性) 鸡肋升级 [小家java]java7新特性(简述八大新特性) 不温不火 [小家java ...

  6. 【Java8新特性 串行/并行流-Optional容器类-时间格式化线程安全等】

    Java8新特性二 一.并行流与顺序流 1.概念 2.Fork/Join框架 3. Fork/Join框架代码示例: 二.Optional类 1. 什么是Optional对象 2. Optional类 ...

  7. 【JAVA拾遗】Java8新特性合辑

    [JAVA拾遗]Java8新特性合辑 文章目录 [JAVA拾遗]Java8新特性合辑 0. 逼逼 [--/--]126 Lambda Expressions & Virtual Extensi ...

  8. Java8新特性学习笔记

    Java8新特性学习笔记 文章目录 Java8新特性学习笔记 一.接口和日期处理 1.接口增强 1.1.JDK8以前 VS JDK8 1)接口定义: 1.2.默认方法(default) 1)默认方法格 ...

  9. 【Java8新特性】关于Java8的Stream API,看这一篇就够了!!

    写在前面 Java8中有两大最为重要的改变.第一个是 Lambda 表达式:另外一个则是 Stream API(java.util.stream.*)  ,那什么是Stream API呢?Java8中 ...

最新文章

  1. 腾讯2009年笔试题
  2. 人工智能机器视觉的未来发展趋势
  3. 更改VS的默认开发语言
  4. 生成对抗网络GANs理解(附代码)
  5. ansi c标准_C/C++的起源与发展故事,我是最牛的软件编程语言,不接受反驳
  6. python人工智能要学什么_为什么学人工智能首推Python 需要学习哪些知识
  7. 牙齿间隙变大怎么办_牙齿之间的间隙越来越大怎么办?
  8. Android全面解析Handler
  9. flux服务器推消息,服务端主动推送数据,除了 WebSocket 你还能想到啥?
  10. Clojure 学习入门(9)- 连接redis
  11. java安全框架下载文件_java安全框架之Permission学习笔记
  12. [渝粤教育] 中国地质大学 计算机组成原理 复习题 (2)
  13. qq永久封号 代码_避免在代码中永久保留这些内容
  14. 三点估算法_三点估算法、方差计算、完工概率计算的讨论
  15. 预加重/去加重/直流滤波
  16. 物联网芯片并非单一产品,目前主要划分为哪几芯片?
  17. 千锋教育python老师_千锋老师分享Python经典面试题
  18. 习题 9.9 商店销售某一商品,商店每天公布统一的折扣(discount)。同时允许销售人员在销售时灵活掌握售价(price),在此基础上,对一次购10件以上者,还可以享受9.8折优惠。
  19. vue判断身份证是否合法
  20. form 表单 onsubmit 属性

热门文章

  1. 7nfs客户端没权限_Ant design pro v4-服务器菜单和路由权限控制
  2. 用html5做一个简单网页_用Python做一个简单的翻译工具
  3. 利用javascript实现简体与繁体的转换
  4. 排序算法(Java实现)
  5. 运放全波整流电路_10种精密全波整流电路
  6. 怎么new一个指针_19. Go语言里的 make 和 new 有什么区别?
  7. 抖音提示需要转换为mp4_如何将MP4文件转换为MP3格式?万兴优转帮你轻松完成转换...
  8. activiti 流程图乱码
  9. 【微信小程序】 自定义导航栏(navigationStyle=custom)
  10. mysql 使用 utf8mb4 编码