《QConShanghai-Roger Ye-Introducing Project Lambda and Invokedynamic.pdf》由会员分享,可在线阅读,更多相关《QConShanghai-Roger Ye-Introducing Project Lambda and Invokedynamic.pdf(43页珍藏版)》请在三一文库上搜索。
1、QCon北京2014大会 4月2527日 InfoQ infoqchina Lambda is coming, are you ready? Agenda Knowing Lambda Typing Invokedynamic Lambda at RunBme About Me 叶瑞华叶瑞华, Roger, ryenus A Java developer ); An Inconvenient Truth about Java List names = Arrays.asList(); List upperNames = new ArrayList(); for (String name : n
2、ames) upperNames.add( name.toUpperCase(); Introducing Lambda (a, b) - a * b x - x + 2 () - 42 (String s) - System.out.println(x) list - list.add(42); return list; Using Lambda new Thread( () - System.out.println(42); ); More Lambda Use Cases Collections.sort(words, (w1, w2) - w1.length() w2.length()
3、; words.forEach(w - System.out.println(x); numbers.stream().filter(n - n 0); words.stream().parallel().map(w - w.toUpperCase(); numbers.stream().reduce(s, n) - s + n); Lambda Benefi ts More Expressive API: forEach, filter, map, reduce Passing code as data, think about Visitor paGern Parallel almost
4、free, as in words.stream().parallel().map() more about this later Gotcha of this Keyword void checkThis() System.out.println(“outer “ + this); / A new Thread(new Runnable() Override public void run() System.out.println(“inner “ + this); / B printThis(); / X? ).start(); new Thread() - System.out.prin
5、tln(this + “ in lambda“).start(); / Y? void printThis() System.out.println(this + “ from printThis()“); Lambda Scope and Naming Lambdas are in the same scope as the enclosing context this refers to the enclosing class Lambda parameters cannot shadow outer local variables Typing Type of Lambdas Are L
6、ambdas Objects? Yes, but you CANNOT do: However you CAN do: Object o = x - System.out.println(x); Consumer c = x - System.out.println(x); Object obj = c; FuncBonal Interfaces Defi niBon InvocaBon FunctionalInterface public interface Consumer void accept(T t); public interface Iterable Iterator itera
7、tor(); default void forEach(Consumer action) Objects.requireNonNull(action); for (T t : this) action.accept(t); Built-in FuncBonalInterface(s) From built-in package: java.util.function Consumer BiConsumer Function BiFunction BinaryOperator Predicate BiPredicate Supplier BooleanSupplier VariaBons: Nu
8、mber of Arguments Function, Supplier Argument Types BiFunction, BinaryOperator Return Types Consumer, Function, Predicate, UnaryOperator, IntToLongFunction * You can also build your own Func3onal Interfaces Default Methods Expanding interfaces without breaking exisBng code public interface Iterable
9、Iterator iterator(); default void forEach (Consumer action) Objects.requireNonNull(action); for (T t : this) action.accept(t); MulB-Inheritance QuesBon: Do we have a confl ict here? interface A default void m() print(“A“); interface B extends A default void m() print(“B“); interface C extends A clas
10、s D implements B, C C c = new D(); c.m(); / A? or B? A.m() B.m() C D Resolving Confl ict interface A default void m() print(“A“); interface B extends A default void m() print(“B“); interface C extends A default void m() print(“C“); /class D implements B,C /Error: duplicate default methods class D im
11、plements B, C public void m() C.super.m(); / new syntax! A.m() B.m() C.m() D Lambda vs. ExisBng Method Lambda x - x + 2 Method: class C int plus2() return x + 2; QuesBon: What informaBon does C.plus2 carry? How about comparing it to the lambda expression? Method References Method references are inte
12、rchangeable with equal lambda expressions List numbers = Arrays.asList(1, 2, 3); / static method, as parameter numbers.stream().map(String:valueOf) / instance method (PrintStream:println), as parameter numbers.forEach(System.out:println) / instance method, as receiver numbers.stream().map(Number:lon
13、gValue) / virtual method, as receiver numbers.sort(Comparable:compareTo) Recursive Lambda Defi niBon? UnaryOperator fib = n - n words = Arrays.asList(“Tom“, “Alex“); words.sort(a, b) - a.length() - b.length(); words.sort(new Comparator() Override public int compare(String a, String b) return a.lengt
14、h() - b.length(); ); Lambda vs. Inner Class Under the Cover The Byte Code InnerClasses: #8; /class Words$1 BootstrapMethods: 0: #37 invokestatic java/lang/invoke/ LambdaMetafactory.metafactory:(Lookup; String; MethodType; MethodType; MethodHandle; MethodType;) CallSite; 14: invokestatic #5 / Method
15、java/util/Arrays.asList 19: invokedynamic #6, 0 / InvokeDynamic #0:compare:()Ljava/util/ Comparator; 24: invokeinterface #7, 2 / InterfaceMethod java/util/ List.sort 35: invokespecial #9 / Method Words$1.“:(LWords;)V 38: invokeinterface #7, 2 / InterfaceMethod java/util/ List.sort invokedynamic Exis
16、Bng InvocaBon InstrucBons InvokestaBc: for staBc methods Invokevirtual: for class methods Invokeinterface: for interface methods Invokespecial: for private methods, constructors, super- calls JVM as a Language Plaform Its now hosts a lot of other language implementaBons JavaScript (Nashorn, dynjs) R
17、uby (JRuby) But JavaScript has prototype based class inheritance Ruby has singleton class Introducing Invokedynamic Invokedynamic is used to make a recipe to construct a lambda instance, including: the funcBonal interface to apply the implementaBon method the captured values The capture site is call
18、ed the lambda factory invoked with invokedynamic, return an instance of the FuncBonal Interface invoked only once, bypassed by future invocaBon The Lambda Metafactory Invokedynamic is used to make a recipe to construct a lambda instance, including: metaFactory(MethodHandles.Lookup caller, / provided
19、 by VM String invokedName, / provided by VM MethodType invokedType, / provided by VM MethodHandle descriptor, / lambda descriptor MethodHandle impl) / lambda body Lambda at RunBme TranslaBon Strategies Lambda is at least as fast as Inner Class Defi nitely could/would be faster in the future Lambda v
20、s. Inner Class - Performance Lambda is at least as fast as Inner Class Defi nitely could/would be faster in the future IDE Support and Gotchas Intellij IDEA and Netbeans works Eclipse Luna early builds available, buggy per my experience QuesBons? Q default void forEach(Consumer action) Objects.requi
21、reNonNull(action); for (T t : this) action.accept(t); default Spliterator spliterator() return Spliterators.spliteratorUnknownSize(iterator(), 0); Library Upgrades Besides adding Lambda support in every corner, other important improvements: Laziness Parallelism MulB-Core systems are everywhere 特别感谢 QCon上海合作伙伴