|
1 | 1 | ##Lambda表达式
|
2 | 2 | - Lambda表达式的使用
|
| 3 | + |
3 | 4 | java8以前的字符串排列,创建一个匿名的比较器对象Comparator然后将其传递给sort方法
|
4 | 5 | ```
|
5 | 6 | List<String> names= Arrays.asList("peter", "anna", "mike", "xenia");
|
@@ -32,3 +33,130 @@ names2.sort(Comparator.nullsLast(String::compareTo));
|
32 | 33 | System.out.println(names2);
|
33 | 34 | ##:[anna, mike, peter, xenia, null]
|
34 | 35 | ```
|
| 36 | +- 函数式接口,方法,构造器 |
| 37 | + |
| 38 | +每一个lambda表达式都对应一个类型,通常是接口类型。而“函数式接口”是指仅仅只包含一个抽象方法的接口, |
| 39 | +每一个该类型的lambda表达式都会被匹配到这个抽象方法。 |
| 40 | +因为默认方法不算抽象方法,所以你也可以给你的函数式接口添加默认方法。 |
| 41 | +我们可以将lambda表达式当作任意只包含一个抽象方法的接口类型,确保你的接口一定达到这个要求,你只需要给你的接口添加 @FunctionalInterface 注解, |
| 42 | +编译器如果发现你标注了这个注解的接口有多于一个抽象方法的时候会报错的。 |
| 43 | + |
| 44 | +函数式接口 |
| 45 | + |
| 46 | +``` |
| 47 | + @FunctionalInterface |
| 48 | + public static interface Converter<F, T> { |
| 49 | + T convert(F from); |
| 50 | + } |
| 51 | + /**原始的接口实现*/ |
| 52 | + Converter<String, Integer> integerConverter1 = new Converter<String, Integer>() { |
| 53 | + @Override |
| 54 | + public Integer convert(String from) { |
| 55 | + return Integer.valueOf(from); |
| 56 | + } |
| 57 | + }; |
| 58 | +
|
| 59 | + /**使用lambda表达式实现接口*/ |
| 60 | + Converter<String, Integer> integerConverter2 = (from) -> Integer.valueOf(from); |
| 61 | +
|
| 62 | + Integer converted1 = integerConverter1.convert("123"); |
| 63 | + Integer converted2 = integerConverter2.convert("123"); |
| 64 | + System.out.println(converted1); |
| 65 | + System.out.println(converted2); |
| 66 | + ##:123 |
| 67 | + 123 |
| 68 | + /**简写的lambda表达式*/ |
| 69 | + Converter<String, Integer> integerConverter3 = Integer::valueOf; |
| 70 | + Integer converted3 = integerConverter3.convert("123"); |
| 71 | + System.out.println(converted3); |
| 72 | + ##:123 |
| 73 | +``` |
| 74 | +函数式方法 |
| 75 | +``` |
| 76 | + static class Something { |
| 77 | + String startsWith(String s) { |
| 78 | + return String.valueOf(s.charAt(0)); |
| 79 | + } |
| 80 | + } |
| 81 | + Something something = new Something(); |
| 82 | + Converter<String, String> stringConverter = something::startsWith; |
| 83 | + String converted4 = stringConverter.convert("Java"); |
| 84 | + System.out.println(converted4); |
| 85 | + ##:j |
| 86 | +``` |
| 87 | +函数式构造器 |
| 88 | +Java编译器会自动根据PersonFactory.create方法的签名来选择合适的构造函数。 |
| 89 | +``` |
| 90 | + public class Person { |
| 91 | + public String firstName; |
| 92 | + public String lastName; |
| 93 | +
|
| 94 | + public Person() { |
| 95 | + } |
| 96 | +
|
| 97 | + public Person(String firstName, String lastName) { |
| 98 | + this.firstName = firstName; |
| 99 | + this.lastName = lastName; |
| 100 | + } |
| 101 | +
|
| 102 | + public String toString(){ |
| 103 | + return firstName+lastName; |
| 104 | + } |
| 105 | + } |
| 106 | +``` |
| 107 | +``` |
| 108 | + interface PersonFactory<P extends Person> { |
| 109 | + P create(String firstName, String lastName); |
| 110 | + } |
| 111 | + PersonFactory<Person> personFactory = Person::new; |
| 112 | + Person person = personFactory.create("xu", "hua"); |
| 113 | + System.out.println(person.toString()); |
| 114 | + ##:xuhua |
| 115 | +``` |
| 116 | +- Lambda作用域 |
| 117 | +在lambda表达式中访问外层作用域和老版本的匿名对象中的方式很相似。 |
| 118 | +你可以直接访问标记了final的外层局部变量,或者实例的字段以及静态变量。 |
| 119 | +``` |
| 120 | + static int outerStaticNum = 10; |
| 121 | +
|
| 122 | + int outerNum; |
| 123 | +
|
| 124 | + void testScopes() { |
| 125 | + |
| 126 | + /**变量num可以不用声明为final*/ |
| 127 | + int num = 1; |
| 128 | +
|
| 129 | + /**可以直接在lambda表达式中访问外层的局部变量*/ |
| 130 | + Lambda2.Converter<Integer, String> stringConverter = |
| 131 | + (from) -> String.valueOf(from + outerStaticNum+num); |
| 132 | + String convert = stringConverter.convert(2); |
| 133 | + System.out.println(convert); |
| 134 | + ##:13 |
| 135 | + /**但是num必须不可被后面的代码修改(即隐性的具有final的语义),否则编译出错*/ |
| 136 | + //num=3; |
| 137 | +
|
| 138 | + /**lambda内部对于实例的字段以及静态变量是即可读又可写*/ |
| 139 | + Lambda2.Converter<Integer, String> stringConverter2 = (from) -> { |
| 140 | + outerNum = 13; |
| 141 | + return String.valueOf(from + outerNum); |
| 142 | + }; |
| 143 | + System.out.println(stringConverter2.convert(2)); |
| 144 | + System.out.println("\nBefore:outerNum-->" + outerNum); |
| 145 | + outerNum = 15; |
| 146 | + System.out.println("After:outerNum-->" + outerNum); |
| 147 | + ##:Before:outerNum-->13 |
| 148 | + After:outerNum-->15 |
| 149 | + |
| 150 | + String[] array = new String[1]; |
| 151 | + Lambda2.Converter<Integer, String> stringConverter3 = (from) -> { |
| 152 | + array[0] = "Hi here"; |
| 153 | + return String.valueOf(from); |
| 154 | + }; |
| 155 | + stringConverter3.convert(23); |
| 156 | + System.out.println("\nBefore:array[0]-->" + array[0]); |
| 157 | + array[0] = "Hi there"; |
| 158 | + System.out.println("After:array[0]-->" + array[0]); |
| 159 | + ##:Before:array[0]-->Hi here |
| 160 | + After:array[0]-->Hi there |
| 161 | + } |
| 162 | +``` |
0 commit comments