Lambda表达式
* Lambda表达式是一种没有名字的函数 , 也可以称之为闭包 , 是Java8的新特性
*
* 本质是一个匿名内部类 , 又叫做箭头函数
*
* 使用它就是为了方便简洁 匿名内部类与箭头函数是一个东西 ,所以两种写法所表示的含义是相同的
*
* 闭包是能够读取其他函数内部变量的函数
*
* 允许把方法作为一个参数传递 , 使用Lambda表达式 , 可以使代码变得更加简洁紧凑
*
* -> : 箭头操作符
*
* 语法结构 :
* 无参无返回值 : Runnable r1 = -> {System.out.println("Hello World");};
*
* 可选类型声明 : 不需要声明数据类型 , 编译器可以识别参数值
* 可选的参数()括号 : 一个参数不需要定义括号 , 但是多个参数必须定义括号
* 可选的大括号 : 如果主体内只有一个语句 , 就可以不加大括号
* 可选的返回值关键字 : 如果主体内只有一个语句 ,且是返回语句 , return就可以不写
* 如果有多条语句 , 大括号和return就都得写
用法 与 对比(1.8之前可以怎么写,之后可以怎么写)
public class Lambda_01_01 {
public static void main(String[] args) {
String[] arr = {"one","two","three","four"};
List<String> list = Arrays.asList(arr);
for (String string : list) {
System.out.println(string);
}
System.out.println("<------------------------------------------->");
list.forEach(x -> System.out.println(x));
System.out.println("<------------------------------------------->");
list.forEach(y -> {
System.out.println(y);
});
}
}
用新写法进行排序
public class Lambda_02 {
public static void main(String[] args) {
Integer[] arr = {2,6,8,1,3,9,5};
List<Integer> list = Arrays.asList(arr);
list.sort(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1;
}
});
System.out.println(list);
list.sort((o1 , o2) -> Integer.compare(o1, o2) );
list.sort((o1 , o2) -> o1-o2 );
System.out.println(list);
}
}
Functional interface 函数式接口
* Functional interface
* 函数式接口 : 本质就是一个只有一个抽象方法 , 但是可以有多个非抽象方法的接口
* 这个接口的目的就是为lambda表达式的使用提供更好的支持 , 进一步达到函数式编程的目标 , 提高开发效率
*
* 特点 : 函数式接口是仅指定一个抽象方法的接口
* 可以保护多个静态方法和默认方法
* 专用注解 : @FuntionalInterface , 检查是否是一个函数式接口 , 也可以不写该注解
* 如果有两个及以上的抽象方法 , 就不能当做函数式接口去使用 , 同时也不能添加 @FuntionalInterface 注解
*
* 回调函数 : 就是方法需要传入一个参数 (参数时方法) , 并且在该方法中对这个传入的方法进行调用
无参时
public class Functional_02_01 {
public static void main(String[] args) {
Test test = new Test();
call(test);
call(new MyFunctionInter() {
@Override
public void printMessage() {
System.out.println("匿名内部类的实现方法");
}
});
call(() -> System.out.println("Lambda表达式的实现方法"));
MyFunctionInter Inter = () -> System.out.println("创建函数对象的实现方法");
call(Inter);
}
public static void call(MyFunctionInter func){
func.printMessage();
}
}
@FunctionalInterface
interface MyFunctionInter{
void printMessage();
}
class Test implements MyFunctionInter{
@Override
public void printMessage() {
System.out.println("Test实现MyFunctionInter接口");
}
}
有参时
public class Functional_02_02 {
public static void main(String[] args) {
String str = "有参数的函数式接口调用";
call(new MyFunctionInter2() {
@Override
public void printMessage(String str) {
System.out.println(str);
}
}, str);
call(x->System.out.println(x), str);
MyFunctionInter2 inter2 = x->System.out.println(x);
call(inter2, str);
}
public static void call(MyFunctionInter2 func , String str){
func.printMessage(str);
}
}
@FunctionalInterface
interface MyFunctionInter2 {
void printMessage(String str);
}
JDK自带的函数式接口
Supplier
* Supplier<T> 接口 : 表示供应商 , 所以有返回值 , 可以获取数据 * 其内只有 get方法
public class Jdk_Own_02 {
public static void main(String[] args) {
String result = SupplierGetRusult(new Supplier<String>() {
@Override
public String get() {
return "杜智慧_1";
}
});
System.out.println(result);
result = SupplierGetRusult(()-> "杜智慧_2");
System.out.println(result);
Supplier<Jdk_Own_02> sup = Jdk_Own_02::new;
Jdk_Own_02 jo1 = sup.get();
Jdk_Own_02 jo2 = sup.get();
System.out.println(jo1);
System.out.println(jo2);
}
public static String SupplierGetRusult(Supplier<String> function){
return function.get();
}
}
Consumer
* Consumer<T>接口 , 表示消费者接口 , 没有返回值
*
* accept(T t) 用于执行消费操作
public class Jdk_Own_03 {
public static void main(String[] args) {
String message = "我是杜智慧";
ConsumerGetRusult(x->System.out.println(x), message);
ConsumerGetRusult(new Consumer<String>() {
@Override
public void accept(String t) {
System.out.println(t);
}
}, message);
}
public static void ConsumerGetRusult(Consumer<String> function , String message){
function.accept(message);
}
}
Function
* Function<T , R> 接口 : 表示接收一个参数 , 并产生一个结果
public class Jdk_Own_04 {
public static void main(String[] args) {
int num = converTyoe(x->Integer.parseInt(x), "123");
System.out.println(num);
Function<String , Integer> x1 = x->Integer.parseInt(x);
int num1 = x1.apply("123");
System.out.println(num1);
}
public static int converTyoe(Function<String , Integer> function , String str){
int num = function.apply(str);
return num;
}
}
Predicate 断言接口
* Predicate<T> 接口 : 断言接口 , 就是做一些判断
* boolean test(T) 用于做校验比较操作
public class Jdk_Own_05 {
public static void main(String[] args) {
String message = "ok";
boolean result = call(x->x.equals("ok"), message);
System.out.println(result);
}
public static boolean call(Predicate<String> predicate , String message){
return predicate.test(message);
}
}
方法和构造器
对象的引用::实例方法
public class FunCall_03_01 {
public static void main(String[] args) {
Integer i1 = new Integer(12356);
Supplier<String> str1 = i1::toString;
System.out.println(str1);
System.out.println(str1.get());
Supplier<String> str2 = ()->i1.toString();
System.out.println(str2);
System.out.println(str2.get());
}
}
类名::静态方法名
public class FunCall_03_02 {
public static void main(String[] args) {
BiFunction<Integer, Integer, Integer> bif = (x,y)->Integer.max(x, y);
int apply = bif.apply(10, 11);
System.out.println(apply);
BiFunction<Integer, Integer, Integer> bif1 = Integer::max;
int apply1 = bif.apply(10, 11);
System.out.println(apply1);
}
}
类名::实例方法
public class FunCall_03_03 {
public static void main(String[] args) {
BiPredicate<String, String> predicate = (x , y)->x.equals(y);
System.out.println(predicate.test("a", "b"));
BiPredicate<String, String> predicate1 = String::equals;
System.out.println(predicate1.test("a", "a"));
}
}
构造器调用
public class ConstructorCall_04 {
public static void main(String[] args) {
Supplier<Object> objsup = ()->new Object();
System.out.println(objsup);
Supplier<Object> objsup1 = Object::new;
System.out.println(objsup1);
Function<String, Integer> function = (x)-> new Integer(x);
System.out.println(function);
Function<String, Integer> function1 = Integer::new;
System.out.println(function1);
}
}
数组引用
public class ArrayCall_05 {
public static void main(String[] args) {
Function<Integer, Integer[]> function = n->new Integer[n];
Integer[] arr = function.apply(10);
System.out.println(arr.length);
Function<Integer, Integer[]> function1 = Integer[]::new;
Integer[] arr1 = function1.apply(11);
System.out.println(arr1.length);
}
}
Stream API
* Java8中有两大最为重要的改变第一个是Lambda 表达式 , 另外一个则是Stream API
* Stream API把真正的函数式编程引入到了Java中 , 这是目前为止对Java类库最好的补充
* Stream API可以极大的提升程序员的上产效率 ,让程序员写出高效率、干净、简洁的代码
*
*
* 简单来讲 , 就是Stream API 提供了一种高效且易于使用的处理数据的方式
*
* Stream 自己不会存储元素 , 不会改变源对象 , 相反 , 他会返回一个新的Stream
* 且Stream操作是延迟执行的 , 就是说 , 他们会等到需要结果的时候才会执行
*
*
* 运行机制 : 分为 源(source) , 中间操作 , 终止操作三部分
*
* 1 创建Stream
* 2 中间操作 : 也叫做转换算子 , 这个操作可以是一个操作链 , 在这个链式操作里 , 这个流一直保持着流的状态
* 3 终止操作 : 也叫做动作算子 , 这是真正执行运算的操作 , 且它的返回值也不再是一个流 , 计算到此终止
创建流的五种方式
public class StreamAPI_01 {
public static void main(String[] args) {
String[] strings = {"a","b","c","d"};
Stream<String> stream1 = Stream.of(strings);
List<String> strings2 = Arrays.asList(strings);
Stream<String> stream2 = strings2.stream();
Stream<Integer> generate = Stream.generate(()->1);
generate.limit(5).forEach(x->System.out.print(x + " "));
System.out.println();
Stream<Integer> iterate = Stream.iterate(1, x->x+2);
iterate.limit(5).forEach(x->System.out.print(x + " "));
System.out.println();
String string = "abc";
IntStream chars = string.chars();
chars.forEach(x->System.out.print(x + " "));
}
}
常用的转换算子
* filter distinct map limit skip faltMap等
*
* filter : 对元素进行过滤 , 不符合条件的就不要
*
* distinct : 去掉重复
*
* map : 可以理解为在遍历集合的过程中 , 对元素进行操作 , 比如进行判断
* 集合元素是否大于2 返回值为Boolean型 , 或者对集合元素进行更改 , 比如 , 每个元素自身加一
* 与filter类似 , 但是filter不能对元素进行更改
*
* limit : 取一个集合中的前几个数据 (也可以理解为设置最大条数)
*
* skip : 跳过多少个元素
*
* faltMap : 解决一个字符串数组 , 返回单一的字符串使用faltMap
*
* 这些算子并不能真正的进行计算 , 只有终止算子(动作算子)会真正进行计算操作
public class StreamAPI_02 {
public static void main(String[] args) {
String[] arr = {"a","b","c","d"};
List<String> strings = Arrays.asList(arr);
Stream<String> stream = strings.stream();
List<String> value = stream.filter(x -> x.equals("a")).collect(Collectors.toList());
System.out.println(value);
stream = strings.stream();
value = stream.skip(1).collect(Collectors.toList());
System.out.println(value);
stream = strings.stream();
List<Boolean> value1 = stream.map(x-> x.equals("a")).collect(Collectors.toList());
System.out.println(value1);
stream = strings.stream();
value = stream.map(x->x+"-->").collect(Collectors.toList());
System.out.println(value);
stream = strings.stream();
value = stream.distinct().collect(Collectors.toList());
System.out.println(value);
String[] arr1 = {"1,2,3" , "a,b,c"};
strings = Arrays.asList(arr1);
stream = strings.stream();
value = stream.map(x->x.split(",")).flatMap(array->Arrays.stream(array)).collect(Collectors.toList());
System.out.println(value);
}
}
常用的动作算子
* forEach : 循环
*
* 用于计算的 : min , max , count , average
*
* 用于匹配的 : anyMatch , allMatch , noneMatch , findFirst , findAny
*
* 汇聚 : reduce
public class StreamAPI_03 {
public static void main(String[] args) {
String[] arr = {"a","b","c"};
List<String> strings = Arrays.asList(arr);
System.out.println(strings);
Stream<String> stream = strings.stream();
stream.filter(x->x.equals(x)).forEach(x->System.out.println(x));
stream = strings.stream();
long count = stream.filter(x->x.equals("a")).count();
System.out.println(count);
stream = strings.stream();
List<String> list = stream.map(x->x).collect(Collectors.toList());
System.out.println(list);
}
}