面试中会被问到的Java8新特性

1). 接口中新增了default和static方法,这两种方法可以有方法体。
其中default修饰的方法,接口实现类的子类可以调用或覆写,static修饰的方法不能,static修饰的方法只能被接口内部调用。如果一个接口实现类同时实现了两个接口且这两个接口中含有同名同参default方法,那这个实现类覆写该方法时,需要指明覆写的是哪个接口。

public class TestImpl implements T1,T2{
	@Override
	public void defaultFunc(){
		T1.super.defaultFunc();
	}
}

2). Lambda表达式
可以把它看做是匿名内部类,使用lambda表达式时,接口必须是函数式接口(ps:被@FunctionalInterface修饰的接口)如果表达式内访问了局部变量,局部变量必须被final修饰;表达式内对静态变量拥有读写权限。

	//接口
	interface T1 {
		public int sum(int a,int b);
	}

	//Java8之前匿名内部类
	T1 t = new T1(){
		@Override
		public int sum(int a, int b){
			return a+b;
		}
	}
	
	//利用lambda表达式实现匿名内部类
	T1 t = (a,b) -> {
		return a+b;
	}
	// 调用
	t.sum(2,5);

	//通过引用实例方法的lambda表达式
	T1 t = System.out::println();
	t.sum("这是参数");
	// t在调用sum方法时,实际参数是传给了out对象,然后执行了println方法,这跟上面的方式原理上是相同的,都是传递参数然后执行逻辑,只是这里的参数直接给到了lambda表达式中的对象,然后去执行对象的方法。

	//通过引用类方法的lambda表达式
	T1 t = Collections::sort;
	t.sum("传入的参数");
	// 这里跟上面是几乎相同的,只是这里lambda定义时用的是 类名.方法 上面用的是 对象.方法

	//通过引用构造器方法的lambda表达式
	T1 t = String::new;
	t.sum(new char[]{'1','2','a','b'});
	// 跟上面也差不多,只是方法换成了构造方法
	
	//引用类的实例方法的lambda表达式
	//这种方式,在定义接口时就要将第一个参数设置为类的实例
	T1 t = TImpl:: sum;
	TImpl timpl = new TImpl();
	t.sum(timpl,2,5);
	//这个跟上面的引用类方法差不多,仔细看首个参数甚至略显多余

3).函数式接口
接口只有一个抽象方法(default方法不算)则称为函数式接口。可以添加@FunctionalInterface注解,这样当不符合规则时编译器会报错提醒你。

4). Java8中对许多接口都添加了一些default默认方法

5). Java8新增了一组全新的时间日期API
包括Instant、LocalDate、LocalDateTime、LocalTime等等,还包含了一个格式器类DateTimeFormater,有了它以后就可以不用SimpleDateFormat或者DateFormat了。
Date类是很糟糕的设计,官方推荐用Calendar工具类。

//创建一个默认的Calendar对象
Calendar calendar = Calendar.getInstance();
 //从Calendar对象中取出Date对象
 Date date = calendar.getTime();

一个Calendar对象包含了很多很多字段属性,所有它有大量的访问方法,常用如下:

1.void add(int field,int amount):根据日历的规则,为给定的日历字段添加或减去指定的时间量。
2.int get(int field):返回指定日历字段的值。
3.int getActualMaximun(int field): 返回指定日历字段可能拥有的最大值。例如月,最大值为11.
4.int getActualMinimun(int field):返回指定日历字段可能拥有的最小值。例如月,最小值为0.
5.void roll(int field,int amount):与add()方法类似,区别在于加上amount后超多了该字段所能表示的最大范围时,也不会向上一个字段进位。
6.void set(int field,int value):将给定的日历字段设置为给定值,set是有延迟性的,这样的好处在于,当多次set时,对之前被覆盖掉的数值,无需额外计算,set是在get()、getTime()、getTimeInMillis()、add()或roll()时才会重新计算日历的时间.
7.void set(int year,int month,int date):设置Calendar对象的年,月,日三个字段的值。
8.void set(int year,int month,int date,int hourOfDay,int minute,int second):设置Calendar对象的年,月,日,时,分,秒6个字段的值。

Calendar类是有容错性的,可通过setLenient()设置,所谓的容错性就是指时间字段允许超过其限制(比如13月),他会自动的向上进位的。
6). Java8新增Stream流API
这个流跟那个输入流输出流不是一回事儿
它是数据渠道,用来操作数据源生成的元素序列
它自己不会存储元素
它不会改变源数据
它的操作有延迟性,需要结果时才执行

Stream流的操作分为三部分:
创建stream -> 中间操作 -> 终端操作

一、创建

//1. Collection 提供了两个方法  stream() 与 parallelStream()
ArrayList<String> list = new ArrayList<>();
Stream<String> stream = list.stream();  //获取一个顺序流
Stream<String> parallelStream = list.parallelStream();  //获取一个并行流
// 这里的并行流是指内部通过多线程来操作这个stream,举个例子,如果list是等量的,那么对这两个流进行排序,并行流完成的速度更快。

//2.通过Arrays中的steam()获取一个数组流
Integer[] nums = new Integer[10];
Stream<Integer> stream1 = Arrays.stream(nums);
//3.通过stream类中静态方法of()
Stream<Integer> stream2 = Stream.of(1, 2, 3, 4, 5, 6);
//4.创建无限流
//迭代
Stream<Integer> stream3 = Stream.iterate(0, (x) -> x + 2).limit(10);
stream3.forEach(System.out::println);

//生成
Stream<Double> stream4 = Stream.generate(Math::random).limit(2);
stream4.forEach(System.out::println);

二、中间操作
中间操作链包含多个中间操作,他们连起来形成一个流水线,除非执行终端操作,否则的话中间操作是不会被触发执行的。中间操作包括:映射、筛选与切片、排序
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
三、终端操作
一个终止操作,执行中间操作链,并产生结果
终端操作会从流的流水线生成结果。其结果可以是任何不是流的值,例如:List、Integer,甚至是void 。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200913205501629.png#pic_center
Collector 接口中方法的实现决定了如何对流执行收集操作(如收集到List、Set、Map)。但是Collectors 实用类提供了很多静态方法,可以方便地创建常见收集器实例,具体方法与实例如下表:
在这里插入图片描述在这里插入图片描述

  List<Employee> emps = Arrays.asList(
			new Employee(102, "李四", 59, 6666.66),
			new Employee(101, "张三", 18, 9999.99),
			new Employee(103, "王五", 28, 3333.33),
			new Employee(104, "赵六", 8, 7777.77),
			new Employee(104, "赵六", 8, 7777.77),
			new Employee(104, "赵六", 8, 7777.77),
			new Employee(105, "田七", 38, 5555.55)
	);
  List<String> list = emps.stream().map(Employee::getName).collect(Collectors.toList());
  list.forEach(System.out::println);
  System.out.println("-----------------");
  Set<String> set = emps.stream().map(Employee::getName).collect(Collectors.toSet());
  set.forEach(System.out::println);
  System.out.println("-----------------");
  HashSet<String> hs = emps.stream().map(Employee::getName).collect(Collectors.toCollection(HashSet::new));
  hs.forEach(System.out::println);

Match匹配

allMatch——检查是否匹配所有元素
anyMatch——检查是否至少匹配一个元素
noneMatch——检查是否没有匹配的元素
findFirst——返回第一个元素
findAny——返回当前流中的任意元素
count——返回流中元素的总个数
max——返回流中最大值
min——返回流中最小值
boolean b1 = emps.stream().allMatch((e) -> e.getStatus().equals(Employee.Status.BUSY));
System.out.println(b1);
boolean b11 = emps.stream().anyMatch((e) -> e.getStatus().equals(Employee.Status.BUSY));
System.out.println(b11);
boolean b12 = emps.stream().noneMatch((e) -> e.getStatus().equals(Employee.Status.BUSY));
System.out.println(b12);

归约
在这里插入图片描述

  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 = emps.stream().map(Employee::getSalary).reduce(Double::sum);
  System.out.println(op.get());

分组

//根据状态分组:
  Map<Employee.Status, List<Employee>> map = emps.stream().collect(Collectors.groupingBy(Employee::getStatus));
        System.out.println(map);
// {VOCATION=[Employee [id=103, name=王五, age=28, salary=3333.33, status=VOCATION]], FREE=[Employee [id=101, name=张三, age=18, salary=9999.99, status=FREE], Employee [id=104, name=赵六, age=8, salary=7777.77, status=FREE], Employee [id=104, name=赵六, age=8, salary=7777.77, status=FREE]], BUSY=[Employee [id=102, name=李四, age=79, salary=6666.66, status=BUSY], Employee [id=104, name=赵六, age=8, salary=7777.77, status=BUSY], Employee [id=105, name=田七, age=38, salary=5555.55, status=BUSY]]}

//根据工资是否大于5000分组:
 Map<Boolean, List<Employee>> map = emps.stream().collect(Collectors.partitioningBy((e) -> e.getSalary() >= 5000));
    System.out.println(map);
// {false=[Employee [id=103, name=王五, age=28, salary=3333.33, status=VOCATION]], true=[Employee [id=102, name=李四, age=79, salary=6666.66, status=BUSY], Employee [id=101, name=张三, age=18, salary=9999.99, status=FREE], Employee [id=104, name=赵六, age=8, salary=7777.77, status=BUSY], Employee [id=104, name=赵六, age=8, salary=7777.77, status=FREE], Employee [id=104, name=赵六, age=8, salary=7777.77, status=FREE], Employee [id=105, name=田七, age=38, salary=5555.55, status=BUSY]]}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

缔曦_deacy

码字不易,请多支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值