jdk8新特性---转载

jdk8新特性

1.接口的静态方法和默认方法

1.1默认方法

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

采用默认理由:接口本身是有弊有利,利:体现面向对象抽象编程而不是面向具体过程编程;弊:当对某一个接口进行修改时,则需要修改全部实现该接口的实现类。因为目前java8之前的集合框架没有foreach方法,通常能想到的解决办法是在JDK里给相关接口添加新的方法及实现,但对于已经发布的版本是没有办法给接口添加新的方法的同时不影响已经有的实现类,所以引进默认方法。目的是为了解决接口的修改与现有实现不兼容的问题。

1.2静态方法

给方法加上static关键字,使其成为静态方法,可写具体实现。

举例

  1. interface Inf{
  2. int add(int a, int b);
  3. default int mul(int a, int b){
  4. return a * b;
  5. }
  6. static double div(double a, double b){
  7. return a / b;
  8. }
  9. }
  10. class InfImp implements Inf{
  11. @Override
  12. public int add(int a, int b) {
  13. return a + b;
  14. }
  15. }
  16. public class InterfaceDemo {
  17. public static void main(String[] args) {
  18. Inf inf = new InfImp();
  19. System.out.println(inf.add( 10, 20));
  20. System.out.println(inf.mul( 10, 20));
  21. System.out.println(Inf.div( 23, 2));
  22. }
  23. }

2.Lambda表达式

Lambda表达式--也可以称为闭包,Lambda允许把函数作为一个方法的参数(函数作为参数传递进方法中),使用Lambda表达式可以使代码变得更加简洁紧凑。

语法:

  1. (parameters) -> expression
  2. (parameters) ->{ statements; }

几大重要特征:

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

举例:

简洁示例;

  1. //传统方式
  2. int add(int a, int b){
  3. return a +b;
  4. }
  5. //lambda表达式
  6. (a,b) -> a + b
  7. //传统方式
  8. int add(int a, int b){
  9. System.out.println(a + b);
  10. return a + b;
  11. }
  12. //lambda表达式
  13. (a, b) -> {
  14. System.out.println(a + b);
  15. return a + b;
  16. }

具体示范:

  1. public class LambdaDemo {
  2. interface inf{
  3. int add(int a,int b) ;
  4. }
  5. public static void main(String[] args) {
  6. //一:传统方法
  7. inf in = new inf() {
  8. @Override
  9. public int add(int a, int b) {
  10. return a+b;
  11. }
  12. };
  13. System.out.println(in.add( 10, 20));
  14. //lambda表达式
  15. inf in2 = (a,b) -> a+b;
  16. System.out.println(in2.add( 20, 30));
  17. //二:Comparator
  18. Comparator<Integer> comparator = new Comparator<Integer>() {
  19. @Override
  20. public int compare(Integer o1, Integer o2) {
  21. return o1-o2;
  22. }
  23. };
  24. //lambda表达式
  25. Comparator<String> comparator2 = (o1,o2) -> o1.length()-o2.length();
  26. }
  27. }

总结注意点:

1.Lambda 表达式主要用来定义行内执行的方法类型接口

2.Lambda 表达式免去了使用匿名方法的麻烦,并且给予Java简单但是强大的函数化的编程能力

3.lambda 表达式只能引用标记了 final 的外层局部变量,这就是说不能在 lambda 内部修改定义在域外的局部变量,否则会编译错误。

4.可以直接在 lambda 表达式中访问外层的局部变量,局部变量可以不用声明为 final,但是必须不可被后面的代码修改(即隐性的具有 final 的语义)

5.在 Lambda 表达式当中不允许声明一个与局部变量同名的参数或者局部变量

3.forEach

用于遍历信息,配合Lamdba一起使用

举例:

  1. public class ForEachDemo {
  2. static Integer sum= 0;
  3. public static void main(String[] args) {
  4. List<Integer> list = new ArrayList<>();
  5. list.add( 1);
  6. list.add( 2);
  7. list.add( 3);
  8. list.add( 4);
  9. list.forEach(e -> {sum += e;});
  10. System.out.println(sum);
  11. Map<Integer, String> map = new HashMap<>();
  12. map.put( 1, "小赐赐");
  13. map.put( 2, "宇宙");
  14. map.put( 3, "无敌");
  15. map.put( 4, "帅");
  16. map.forEach((k,v) -> System.out.println(k+ "="+v));
  17. }
  18. }

结果如图:


4.方法引用

方法引用通过方法的名字来指向一个方法,使用一对冒号 :: 可以使语言的构造更紧凑简洁,减少冗余代码。

注意:

如果Lambda表达式中仅仅调用一个已经存在的方法,那么可以通过方法名来引用这个已经存在的方法。被引用的方法要加上::。需要注意的是----定义的方法与方法体内调用的方法参数和返回值类型必须相同。

语法:

1.构造器引用:它的语法是Class::new,或者更一般的Class< T >::new

2.静态方法引用:它的语法是Class::static_method

3.特定类的任意对象的方法引用:它的语法是Class::method

4.特定对象的方法引用:它的语法是instance::method

应用实例:

  1. public class MethodReferenceDemo {
  2. interface Inf{
  3. void output(int a) ;
  4. }
  5. interface InfTwo{
  6. public String create(String x);
  7. }
  8. public static void main(String[] args) {
  9. //匿名类
  10. Inf inf1 = new Inf() {
  11. @Override
  12. public void output(int a) {
  13. System.out.println(a);
  14. }
  15. };
  16. //lambda
  17. Inf inf2 = a ->System.out.println(a);
  18. //方法引用
  19. Inf inf3 = System.out::println;
  20. List<Integer> list = new ArrayList<>();
  21. list.add( 1);
  22. list.add( 2);
  23. list.add( 3);
  24. list.forEach(System.out::println);
  25. //new
  26. InfTwo infTwo2 = String:: new;
  27. System.out.println(infTwo2.create( "小赐赐"));
  28. //等同于 匿名内部类
  29. InfTwo infTwo = new InfTwo() {
  30. @Override
  31. public String create(String x) {
  32. return x;
  33. }
  34. };
  35. }
  36. }

5.stream

是对集合或数组进行操作的一个工具。

特点:

元素是特定类型的对象,形成一个队列。 Java中的Stream并不会存储元素,而是按需计算。

数据源流的来源。 可以是集合,数组,I/O channel, 产生器generator 等。

聚合操作类似SQL语句一样的操作, 比如filter, map, reduce, find, match, sorted等。

Pipelining: 中间操作都会返回流对象本身。 这样多个操作可以串联成一个管道。

内部迭代: 以前对集合遍历都是通过Iterator或者For-Each的方式, 显式的在集合外部进行迭代, 这叫做外部迭代。 Stream提供了内部迭代的方式, 通过访问者模式(Visitor)实现。


获取Stream的常用方式

    A.stream() − 为集合创建串行流。

    B.parallelStream() − 为集合创建并行流。

public static Stream of(T... values)Stream的常用操作分类

    A.Intermediate方法

    B.Terminal方法

    C.Short-circuiting方法

常用操作分类具体如下:

A、Intermediate方法
  1.concat
concat方法将两个Stream连接在一起,合成一个Stream
Stream.concat(Stream.of(1, 2, 3, 4), Stream.of(4, 5, 6 , 7)).forEach(System.out::println);
  2.distinct
distinct方法以达到去除掉原Stream中重复的元素,生成的新Stream中没有没有重复的元素
Stream.concat(Stream.of(1, 2, 3, 4), Stream.of(4, 5, 6 ,7)).distinct().forEach(System.out::println);
  3.filter
filter方法对原Stream按照指定条件过滤,在新建的Stream中,只包含满足条件的元素,将不满足条件的元素过滤掉
Stream.of(1, 2, 3, 4, 5, 6).filter(e -> e % 2 == 0).forEach(System.out::println);
  4.map
map方法将对于Stream中包含的元素使用给定的转换函数进行转换操作,新生成的Stream只包含转换生成的元素
list.stream().map(e -> e.toUpperCase()).forEach(System.out::println);
  5.sorted
sorted方法将对原Stream进行排序,返回一个有序列的新Stream
list.stream().sorted((o1, o2) -> o1.length() - o2.length()).forEach(System.out::println);
B、Terminal方法
  1.collect
将流重新生成列表
List<Integer> list2 = Stream.of(1, 2, 3, 4, 5, 6).filter(e -> e % 2 ==0).collect(Collectors.toList());
  2.forEach
其用于遍历Stream中的所元素,避免了使用for循环,让代码更简洁,逻辑更清晰
  3.count
count方法将返回Stream中元素的个数。
long v = Stream.of(1, 2, 3, 4, 5, 6).filter(e -> e % 2 == 0).count();
  4.min
min方法根据指定的Comparator,返回一个Optional,该Optional中的value值就是Stream中最小的元素
String min = list.stream().min((o1, o2) -> o1.length() - o2.length()).get();
  5.max
max方法根据指定的Comparator,返回一个Optional,该Optional中的value值就是Stream中最大的元素
String max= list.stream().max((o1, o2) -> o1.length() - o2.length()).get();
C、Short-circuiting方法
  1.allMatch
allMatch操作用于判断Stream中的元素是否全部满足指定条件。如果全部满足条件返回true,否则返回false。
boolean b = Stream.of(10, 2, 30, 4, 50, 6).allMatch(e -> e % 2 == 0);
  2.anyMatch
anyMatch操作用于判断Stream中的是否有满足指定条件的元素。如果最少有一个满足条件返回true,否则返回false。
boolean b2 = Stream.of(10, 2, 3, 4, 50, 6).anyMatch(e -> e % 2 == 0);
  3.findFirst
findFirst操作用于获取含有Stream中的第一个元素的Optional,如果Stream为空,则返回一个空的Optional。
Integer i = Stream.of(10, 2, 3, 4, 50, 6).findFirst().get();
  4.limit
limit方法将截取原Stream,截取后Stream的最大长度不能超过指定值N。如果原Stream的元素个数大于N,将截取原Stream的前N个元素;如果原Stream的元素个数小于或等于N,将截取原Stream中的所有元素。
Stream.of(10, 2, 3, 4, 50, 6).limit(3).forEach(System.out::println);
  5.noneMatch

noneMatch方法将判断Stream中的所有元素是否满足指定的条件,如果所有元素都不满足条件,返回true;否则,返回false.

boolean b3 = Stream.of(101, 21, 301, 41, 501, 61).noneMatch(e -> e % 2 == 0);

举例:

  1. import java.util.ArrayList;
  2. import java.util.List;
  3. import java.util.stream.Collector;
  4. import java.util.stream.Collectors;
  5. import java.util.stream.Stream;
  6. public class StreamDemo {
  7. public static void main(String[] args) {
  8. List<String> list = new ArrayList<>();
  9. list.add( "abv");
  10. list.add( "ddee");
  11. list.add( "jheee");
  12. list.add( "dd");
  13. //filter
  14. Stream.of( 1, 2, 3, 4, 5, 6).filter(e -> e% 2== 0).forEach(System.out::print);
  15. System.out.println();
  16. //concat
  17. Stream.concat(Stream.of( 1, 2, 3), Stream.of( 1, 2, 3, 4)).forEach(System.out::print);
  18. System.out.println();
  19. //distinct
  20. Stream.concat(Stream.of( 1, 2, 3), Stream.of( 1, 2, 3, 4)).distinct().forEach(System.out::print);
  21. System.out.println();
  22. //map
  23. list.stream().map(e -> e.toUpperCase()).forEach(System.out::print);
  24. System.out.println();
  25. //sorted
  26. list.stream().sorted((o1,o2) -> o1.length()-o2.length()).forEach(System.out::println);
  27. System.out.println();
  28. //collect
  29. List<Integer> list2 = Stream.of( 1, 2, 3, 4, 5, 6).filter(e -> e% 2== 0).collect(Collectors.toList());
  30. System.out.println(list2);
  31. //count
  32. long v = Stream.of( 1, 2, 3, 4, 5, 6).count();
  33. System.out.println(v);
  34. //min
  35. String min = list.stream().min((o1,o2) -> o1.length()-o2.length()).get();
  36. System.out.println(min);
  37. //max
  38. String max = list.stream().max((o1,o2) -> o1.length()-o2.length()).get();
  39. System.out.println(max);
  40. //allMatch
  41. boolean allMatch = Stream.of( 1, 2, 3, 4, 5, 6).allMatch(e -> e% 2== 0);
  42. System.out.println(allMatch);
  43. //anyMatch
  44. boolean anyMatch = Stream.of( 1, 2, 3, 4, 5, 6).anyMatch(e -> e% 2== 0);
  45. System.out.println(anyMatch);
  46. //noneMatch
  47. boolean noneMatch = Stream.of( 1, 2, 3, 4, 5, 6).noneMatch(e -> e% 2== 0);
  48. System.out.println(noneMatch);
  49. //findFirst
  50. Integer fInteger = Stream.of( 1, 2, 3, 4, 5, 6).findFirst().get();
  51. System.out.println(fInteger);
  52. //limit
  53. Stream.of( 1, 2, 3, 4, 5, 6).limit( 3).forEach(System.out::print);
  54. }
  55. }

结果如下:


6.新的日期时间API

LocalDateTime年月日十分秒

LocalDate日期

LocalTime时间

举例:

  1. import java.time.LocalDateTime;
  2. import java.time.ZoneId;
  3. import java.time.format.DateTimeFormatter;
  4. import java.util.Date;
  5. public class LocalDateTimeDemo {
  6. public static void main(String[] args) {
  7. //获取系统时间
  8. LocalDateTime localDataTime = LocalDateTime.now();
  9. System.out.println(localDataTime);
  10. //转换
  11. String time = localDataTime.format(DateTimeFormatter.ofPattern( "yy-MM-dd HH-mm-ss"));
  12. System.out.println(time);
  13. //Date转换
  14. Date date = Date.from(localDataTime.atZone(ZoneId.systemDefault()).toInstant());
  15. System.out.println(date);
  16. LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
  17. System.out.println(localDataTime);
  18. System.out.println(localDataTime.getYear());
  19. System.out.println(localDataTime.plusYears( 1).getYear());
  20. System.out.println(localDataTime.minusYears( 1).getYear());
  21. }
  22. }

具体结果如下:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值