Javase——Java8新特性

Java8新特性

新特性简介

1、速度更快

2、代码更少(增加了新的语法:lambda表达式)

3、强大的Steam ApI

4、便于并行

5、最大化减少空指针异常:optional

6、Nashorn 引擎,允许在JVM上运行JS应用

 

 

(一)Lambda 匿名表达式

 

“类型推断”——lambda表达式的类型依赖于上下文环境,是有编译器推断出来的

类型推断是根据 = 左边声明的数据类型,通常左边是接口类型,接口中抽象方法

我的理解:类型推断就是以接口中的抽象方法为模板 进行方法的刻录 我称之为给形参赋值的形参

lambda 是一个匿名函数,可以把lambda表达式理解为一段可以传递的代码。

可以写出更简洁、更灵活的、更紧凑的代码风格,是java的语言表达能力得到提升

 

lambd表达式 是Java语言中引入的一种新的语法元素和操作符

- > 操作符被称为lambda操作符,它将lambda分为两个部分

 

左侧:指定了lambda表达式需要的参数列表

右侧:指定了lambda体,是抽象方法的实现逻辑,也是lambda表达式要执行的功能

import org.junit.Test;

interface MyInterface{
	void test(String str);
}


public class LambdaTest{
	@Test
	public void test1() {
		MyInterface mi = new MyInterface() {

		@Override
		public void test(String str) {
			System.out.println(str);
			}
		};
		mi.test("匿名对象方法调用");
		
		
		MyInterface mi2 = (String str) ->{
			System.out.println(str);
		};
		mi2.test("lambda 匿名表达式");
	}
}

 

(二)函数式接口

只有一个抽象方法的接口称之为函数式接口

 

@FunctionalInterface 注解:检查该接口是否式一个函数式接口

 

Java内置四大核心函数式接口

 

消费型接口:有输入没输出

Consumer 消费器,消费一个T类型的对象

void xxx (T t) 有参无返回值

 

抽象方法: void accept(T t)

@Test
public void test1() {
    Consumer consumer1 = new Consumer() {
		@Override
		public void accept(String t) {
			System.out.println(t);
		}
	};
	consumer1.accept("abc");
	Consumer consumer2 = t -> System.out.println(t);
	consumer2.accept("123");
}

 

供给型接口:没输入有输出

Supplier 供给器 产生一个 类型的对象

T xxx() 无参有返回值

 

抽象方法: T get()

@Test
public void test3() {
	Supplier supplier1 = new Supplier() {
		@Override
		public Student get() {
			return new Student(1,"小王",2,50.1);
		}
	};
	System.out.println(supplier1.get());
	Supplier supplier2 = () -> new Student(21,"小李",32,550.1);
	System.out.println(supplier2.get());
}

函数型接口:有输入有输出

Function 转换器 输入一个T类型的对象,输出返回一个R类型的对象

R xxx(T t) 有一个参 有返回 有输入有输出

 

抽象方法:R apply(T t)

 

@Test
public void test4() {
	Function function1 = new Function(){
		@Override
		public String apply(Integer t) {
			return String.valueOf(t);
		}
	};
	System.out.println(function1.apply(123));
	Function function2 = t -> t.toString();
	System.out.println(function2.apply(123));
}

判定型接口:有参 返回值为boolean

Predicate 判定器 输入一个T类型的对象,进行某种判断,返回一个布尔

boolean xxx 有一个参 有返回值 并且返回值类型为boolean 有输入有输出

 

抽象方法 :boolean test(T t)

@Test
public void test6() {
	Predicate predicate1 = new Predicate() {
		@Override
		public boolean test(Integer t) {
			return t%2 != 0;
		}
	};
	System.out.println(predicate1.test(1));
	Predicate predicate2 = t -> t%2 != 0;
	System.out.println(predicate2.test(2));
}

(三)方法引用与构造器引用

方法引用

当要传递给lambda体的操作,已经有实现的方法了,可以使用方法引用

 

方法引用:lambda表达式作为函数式接口的一个实例,通过方法的名字来指向一个方法

方法引用要求:实现抽象方法参数列表和返回值类型,必须与方法引用的方法的参数列表和返回值类型保持一致

 

方法引用:使用操作符 " : : " 将类与方法名分隔开。

 

方法引用的三种情况:

1、对象 :: 实例方法名

2、类::静态方法名

3、类::实例方法名

 

构造器引用

把构造器引用赋值给定义的方法,要求构造器参数列表要与接口中抽象方法的参数列表一致,

且方法的返回值即为构造器对应类的对象

Function fun = (n) - > new MyClass() 
// 等同于 
Function fun = MyClass::new;

 

数组引用

格式:type[] :: new

Function fun = (n) -> new Integer[n]; 
// 等同于 
Function fun = Integer[]:: new;

 

(四)强大的Stream API

Stream API(java.util.stream) 把真正的函数式编程风格引入到Java中

Stream API 是Java8中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。

 

使用Stream API 对集合数据进行操作,类似于使用SQL执行的数据库查询

Steam API 提供了一种高效且易于使用的处理数据的方式。

 

Stream是数据渠道,用于操作数据源(集合、数组)所生成的元素序列

 

Stream特点

1、Stream不是集合,自己不会存储元素

2、Stream不会改变源对象,每次操作会返回一个新的Stream

3、Stream操作是延迟操作,必须搞清楚有那些数据才能往下执行

4、Stream只能消费一次,如果想继续做其他操作,需要重新获取Stream对象

5、更像一个高级的iterator, 单向,不可王府,数据只能遍历一次,遍历过一次后即用尽

 

Stream操作三个步骤

1、创建Stream

一个数据源(如;集合、数组),获取一个流

创建Stream四种方式:

方式一:通过集合

Java8中的Collection接口被扩展,提供了两个获取流的方法:

default Stream stream():返回一个顺序流

default Stream parallelStream(): 返回一个并行流

@Test 
public void test1() { 
    List list = StudentData.getList(); 
    Stream stream = list.stream(); 
    stream.forEach(System.out::println); 
}

 

方式二:通过数组

Java8 中的 Arrays 的静态方法 stream() 可以获取数组流:

static Stream stream(T[] array): 返回一个流

@Test 
public void test2() { 
    Integer[] arr = {2,3,9,10}; 
    Stream stream = Arrays.stream(arr); 
    stream.forEach(System.out::println); 
}

 

方式三:通过散数据

可以调用Stream类静态方法 of(), 通过显示值创建一个流。它可以接收任意数量的参数。

lpublic static Stream of(T... values) : 返回一个流

@Test 
public void test3() { 
    Stream of = Stream.of("abc","qqq","yyy"); 
    of.forEach(System.out::println); 
}

 

方式四:使用供给器

可以使用静态方法 Stream.iterate() 和 Stream.generate(), 创建无限流。

迭代

public static Stream iterate(final T seed, final UnaryOperator f)

生成

public static Stream generate(Supplier s)

@Test 
public void test4() { 
    Stream stream = Stream.generate(Math::random); 
    stream.forEach(System.out::println); 
}

2、中间操作

一个中间操作链,对数据源的数据进行处理

filter(判定器) : 把流中的所有对象都经过判断器, 如果结果是true留下, 如果是false丢弃.

@Test 
public void test6() { 
    List list = StudentData.getList(); 
    list.stream().filter(t -> t.getScore()>59).filter(t->t.getGrade() ==2                                                 ).forEach(System.out::println); 
} 

@Test 
public void test5() { 
    List list = StudentData.getList(); 
    list.stream().filter(t -> t.getScore()>59).forEach(System.out::println); 
}

3、终止操作

一旦执行终止操作,就执行中间操作链,并产生结果,之后,不会再被使用。

forEach(消费器)

stream.forEach(System.out::println);

Stream的中间操作

筛选和切片操作

Javase——Java8新特性_第1张图片

映射操作

 

 

Javase——Java8新特性_第2张图片

 

排序操作

Javase——Java8新特性_第3张图片

 

 

终止操作

•终端操作会从流的流水线生成结果。其结果可以是任何不是流的值,例如:List、Integer,甚至是 void 。

•流进行了终止操作后,不能再次使用。

 

匹配和查找

 

Javase——Java8新特性_第4张图片

 

Javase——Java8新特性_第5张图片

 

归约操作

Javase——Java8新特性_第6张图片

 

备注:map 和 reduce 的连接通常称为 map-reduce 模式,因 Google 用它来进行网络搜索而出名。

 

收集操作

 

Javase——Java8新特性_第7张图片

 

Javase——Java8新特性_第8张图片

(五)JDK中的Optional类

 

Optional 类(java.util.Optional) 是一个容器类,代表一个值存在或不存在,原来用 null 表示一个值不存在,现在 Optional 可以更好的表达这个概念。并且可以避免空指针异常。

常用方法:

Optional.empty() : 创建一个空的 Optional 实例

Optional.of(T t) : 创建一个 Optional 实例

Optional.ofNullable(T t):若 t 不为 null,创建 Optional 实例,否则创建空实例

isPresent() : 判断是否包含值

T get(): 如果调用对象包含值,返回该值,否则抛异常

orElse(T t) :  如果调用对象包含值,返回该值,否则返回t

orElseGet(Supplier s) :如果调用对象包含值,返回该值,否则返回 s 获取的值

map(Function f): 如果有值对其处理,并返回处理后的Optional,否则返回 Optional.empty()

flatMap(Function mapper):与 map 类似,要求返回值必须是Optional

 

 

为了解决空指针异常,引入Optional类

Optional类实际上是个容器,可以保存类型T的值,可以保存null

 

Optional提供很多方法,可以不用显示进行空值检测

 

Optional类的Javadoc描述:这是一个可以为null的容器对象,如果值存在,

则isPresent()方法会返回true,调用get()方法会返回该对象

 

 

你可能感兴趣的:(javase)