Java Lambda表达式是一种匿名函数,他是没有声明的方法,即没有访问修饰符,返回值声明和名字 1. 传递行为,而不仅仅是值 Lambda 箭头左侧(参数)->箭头右侧(执行体) 当左侧没有参数时 左侧括号是不能省略的 关于函数式接口: doc文档 doc文档 当调用该接口可以直接使用Lambda表达式操作 如accept方法 ( T x)->方法体 打印结果 传统外部迭代:通过下标一个一个迭代出数据(for循环 增强for 迭代器) 例3:将集合英文变成大写 例4 在例三中stream().map(Function<? super T, ? extends R> mapper) Function中两个默认方法 一个静态方法 例6 打印结果概要
作用
2. 提升抽象层次
3. API重用性更好
4. 更加灵活Lambda结构
public class Test1 { public static void main(String[] args) { List<Integer> list = Arrays.asList(1, 3, 8); /* 1. @FunctionalInterface 凡是一个类加上该注解 都是函数式接口 请注意,加了改接口可以使用 lambda表达式、方法引用或构造函数引用。 2.满足以下规则 不然系统会给你生成一个错误信息 1.类型是接口类型,而不是批注类型、枚举或类 2.满足函数式接口要求 */ list.forEach(new Consumer<Integer>() { @Override public void accept(Integer integer) { System.out.println(integer); } }); } }
1.如果一个接口只有一个抽象方法,那么改接口就是一个函数式接口
2.如果我们在某个接口声明@FunctionalInterface注解,那么编译就会暗中函数式接口定义来要求该接口
3.如果某个接口只有一个抽象方法,但我们并没有该接口声明@FunctionalInterface注解。那么编译器依旧会将该接口看做函数式接口。
4.注意,函数接口的实例可以用lambda表达式、方法引用或构造函数引用创建Iterable
jdk1.5 ,实现该接口的类可以进行迭代 ,1.8以后集合都可以直接使用默认方法forEach方法进行迭代 (jdk8之后 接口可以写默认方法和 static实现方法)
forEach
对Iterable的每个行为执行给定的操作,直到处理完所有行为或操作引发异常为止。除非实现类另有指定,否则按迭代顺序(如果指定了迭代顺序)执行操作。操作引发的异常将取决于调用方
forEach改方法是将==行为动作(函数 在java中一种特别的对象)==当做参数进行传递 在jdk1.8之前方法参数只能传递值
实例1public class Test1 { public static void main(String[] args) { List<Integer> list = Arrays.asList(1, 3, 8); /* 1. @FunctionalInterface 凡是一个类加上该注解 都是函数式接口 请注意,加了改接口可以使用 lambda表达式、方法引用或构造函数引用。 2.满足以下规则 不然系统会给你生成一个错误信息 1.类型是接口类型,而不是批注类型、枚举或类 2.满足函数式接口要求 */ list.forEach(new Consumer<Integer>() { @Override public void accept(Integer integer) { System.out.println(integer); } }); list.forEach(x-> System.out.println(x)); Consumer<Integer> s = x-> System.out.println(x); } }
Consumer(重要)
代表着一个接受单个输入参数且不返回结果的操作。与大多数其他函数式接口不同,消费者希望通过副作用(就是可能会去修改接收单个参数)进行操作。类似Test1中accept执行给定行为具体操作给定的行为参数即可
实例2@FunctionalInterface interface MyIterfece { void test(); // void test2(String s); /* 为什么函数式接口里有两个抽象方法 系统不报错 因为 该接口的实现类 一定继承于Object基类 基类存在toString()方法 无需实现类进行创建 所以函数式接口允许存在 Object基类的抽象方法 */ @Override String toString(); } class Test2 { public void meTest(MyIterfece myIterfece) { System.out.println("1"); myIterfece.test(); System.out.println("2"); } public static void main(String[] args) { Test2 test2 = new Test2(); test2.meTest(new MyIterfece() { @Override public void test() { System.out.println("mytest"); } }); /* 当函数式接口里的方法没有参数时 ()不能省略 因为函数式接口只有一个抽象方法 所以方法名就不那么重要 */ test2.meTest(() -> System.out.println("mytest")); System.out.println("===================================="); //等同于MyIterfece接口实现类 MyIterfece myIterfece = () -> System.out.println("mytest"); System.out.println(myIterfece.getClass()); System.out.println(myIterfece.getClass().getSuperclass()); //打印该实现类实现的接口 System.out.println(myIterfece.getClass().getInterfaces()[0]); } }
/* 1 mytest 2 1 mytest 2 ==================================== MyIterfece接口的实现类 class com.shengsiyuan.jdk8.Test2$$Lambda$2/1603195447 实现类接口的父类 class java.lang.Object 实现类实现的接口 interface com.shengsiyuan.jdk8.MyIterfece */
内部迭代: 从内部以一个取出数据 public class Test3 { public static void main(String[] args) { // /* // 对于lambda表达式来说 完全不用管函数式接口里方法名是什么,因为其实通过上下文进行类型推断 // 只需要关系返回值和参数即可 // */ // TheInterface theInterface = () -> { // }; // System.out.println(theInterface.getClass().getInterfaces()[0]); // // TheInterface2 theInterface2 = () -> { // }; // System.out.println(theInterface2.getClass().getInterfaces()[0]); // // //lambda表达式必须依附上下文定位到对应类型 如果没有上下文就会报错 //// ()->{}; // // // new Thread(() -> System.out.println("thread")).start(); //将集合英文变成大写 List<String> list = Arrays.asList("hello", "world", "hello world"); // List<String> list2 = Lists.newArrayList(); // list.forEach(x -> list2.add(x.toUpperCase())); // list2.forEach(x -> System.out.println(x)); /* 采用stream流的方式来编写 map 映射的意思就是将一个值映射为另外一个值 Stream方法中也有个forEach方法作用类似Iterable接口的forEach */ // list.stream().map(x -> x.toUpperCase()).forEach(y -> System.out.println(y)); /* 采用方法引用的方式 x -> x.toUpperCase() 等价于 String::toUpperCase */ list.stream().map(String::toUpperCase).forEach(System.out::println); /* Function<String,String> 输入是调用toString lambda对象的第一个参数 x(也就是String对象) ( x -> x.toUpperCase() 等价于 String::toUpperCase) 输出是toString方法返回的值 */ Function<String, String> function = String::toString; System.out.println(function.getClass().getInterfaces()[0]); } @FunctionalInterface interface TheInterface { void myMethod(); } @FunctionalInterface interface TheInterface2 { void myMethod2(); } }
public class StringComparator { public static void main(String[] args) { /* 集合倒叙排序 */ List<String> list = Arrays.asList("zhangsan", "zhaojie", "maliu"); Collections.sort(list, (x, y) -> x.compareTo(y)); System.out.println(list); } }
Function(重要)
Function<String,String> 输入:是调用toString lambda对象的第一个参数 x(也就是String对象) ( x -> x.toUpperCase() 等价于 String::toUpperCase) 返回:是toString方法返回的值 */ Function<String, String> function = String::toString; System.out.println(function.getClass().getInterfaces()[0]); //map参数就是Function<T,R> 此时 将x当做参数,x.toUpperCase() 当做值返回 list.stream().map(x -> x.toUpperCase()).forEach(y -> System.out.println(y));
例5public class FunctionTest { public static void main(String[] args) { FunctionTest functionTest = new FunctionTest(); System.out.println(functionTest.function(5, x -> x * 2)); /* x -> x +2 是一个行为 当调用方法时他将 x +2 这种行为动作传过去 执行到function.apply(a)时 此时才会执行改行为 执行完返回对应数据 此时行为是用的时候传过去对应的行为(加减乘除) */ System.out.println(functionTest.function(10, x -> x + 2)); System.out.println(functionTest.function(10, x -> x * x)); System.out.println(functionTest.function2(10, x -> x + "你好啊!")); //传统方式 System.out.println(functionTest.method(2)); } //接受一个参数和一个行为 public int function(int a, Function<Integer, Integer> function) { Integer apply = function.apply(a); return apply; } public String function2(int a, Function<Integer, String> function) { String apply = function.apply(a); return apply; } /* 传统方法,我们需要提前将行为定义好 再去调用对应的方法 在运行之前行为都是定义好的做不到灵活多变 */ public int method(Integer a) { return a * 5; } public int method2(Integer a) { return a + 2; } public int method3(Integer a) { return a * a; } }
10 12 10你好啊!
/* 总是返回始终返回调用方 其输入参数的函数 */ static <T> Function<T, T> identity() { return t -> t; } /* 组合函数 将传过来的Function行为apply执行结果 当做第二个Function的行为的执行参数 返回apply结果 */ default <V> Function<V, R> compose(Function<? super V, ? extends T> before) { Objects.requireNonNull(before); return (V v) -> apply(before.apply(v));//返回结果 } /** 组合函数 与上面相反 是将当前的Function行为apply执行结果 当做传过来Function的行为的执行参数 返回apply结果 */ default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) { Objects.requireNonNull(after); //t = 当前Function调用andThen的对象行为 return (T t) -> after.apply(apply(t)); }
Function<String, String> function3 = y -> y + "1"; Function<String, String> function2 = x -> x + "nihao"; //将String对象 传过去 Function<String, String> andThen = function2.andThen(function3); Function<String, String> compose = function2.compose(function3); //返回结果根据用户传过来的的行为决定 ,参数再去执行对应的行为 String andThenapply = andThen.apply("22"); System.out.println(andThenapply); System.out.println("======================================="); String composeapply = compose.apply("22"); System.out.println(composeapply);
22nihao1 ======================================= 221nihao//先执行y -> y + "1".apply("22") 得到的结果221 在执行 x -> x + "nihao".apply(221)
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算