SlideShare a Scribd company logo
1 of 103
Download to read offline
Java 8
@kojilin
2014/03/29@TWJUG
•務必確認 Release Notes
•What s New
•Known Issue
•Compatibility Guide
Java SE 8 新功能
•JSR 308 Annotations on Java Types
•JSR 310 Date and Time API
•JSR 335 Lambda Expressions for the
Java Programming Language
Java SE 8 更新
•JSR 114 JDBC Rowsets
•JSR 160 JMX Remote API
•JSR 173 Java Compiler API
•JSR 199 Streaming API for XML
•JSR 221 JDBC 4.0
•JSR 269 Pluggable Annotation-Processing API
JEP
Lambda
Why Lambda?
•Multicore 時代, 寫能善加利用此環境的應
用程式
•Java 已經有各種支援多執行緒的 API
•平行和非平行的寫法差異大
•Fork-join 仍不夠
•需要一些語法上的改進,以便設計更好的函式
庫
int highScore = 0;
for (Student student : students) {
if (student.age != 20) {
continue;
}
if (student.score > highScore) {
highScore = student.score;
}
}
students.stream()
.filter(new Predicate<Student>() {
@Override 

public boolean test(final Student student) {
return student.age == 20;
}
})
.mapToInt(new ToIntFunction<Student>() {
@Override 

public int applyAsInt(final Student student) {
return student.score;
}
})
.max();
!
students.stream()
.filter( student -> student.age == 20)
.mapToInt( student -> student.score )
.max();
Functional Interface
•在 Java API 中常見到只有一個需要實作的抽
象方法的 interface
•Runnable, Callable, Comparator ...
Anonymous Inner Class
List<String> list = new ArrayList<>();
...
list.stream().sorted(

new Comparator<String>(){

@Override 

public void compare(String o1, 

String o2) {

return o1.compareTo(o2);

}

});
Lambda Expression
List<String> list = new ArrayList<>();
...
list.stream().sorted((o1, o2) -> {
return o1.compareTo(o2);
});
list.stream().sorted(

new Comparator<String>(){

@Override 

public void compare(String o1, 

String o2) {

return o1.compareTo(o2);

}

});
•可以從 sorted 方法知道是 Comparator
list.stream().sorted(

new Comparator<String>(){

@Override 

public void compare(String o1, 

String o2) {

return o1.compareTo(o2);

}

});
•因為是 Comparator 所以知道要實作 compare
list.stream().sorted(

new Comparator<String>(){

@Override 

public void compare(String o1, 

String o2) {

return o1.compareTo(o2);

}

});
•可以知道 compare 方法的參數是兩個字串
list.stream().sorted(

(o1, o2) -> {

return o1.compareTo(o2);

});
•Anonymous functions
•Lambda expression 會轉換成 functional
interface 的實體
•因此 lambda 必須放在要能推論的地方
•編譯器會依照 lambda 對應的 functional
interface,推斷 parameter type
new Comparator<String>(){

@Override 

public void compare(String o1, 

String o2) {

return o1.compareTo(o2);

}

}
!
(o1, o2) -> {
return o1.compareTo(o2);
}
Lambda Syntax
(int x, int y) -> x + y
(int x, int y) -> x + y
Argument List
(int x, int y) -> x + y
Arrow Token
(int x, int y) -> x + y
Body
(int x, int y) -> x + y
() -> 42
(String s) -> { 

System.out.println(s); 

}
•Body is expression
•Body is statement block
(String s) -> 

System.out.println(s)
•Body is a void method invocation
!
(o1, o2) -> {
return o1.compareTo(o2);
}
!
!
!
(o1, o2) -> o1.compareTo(o2)
!
(o1, o2) -> {
return o1.compareTo(o2);
}
!
!
!
(o1, o2) -> o1.compareTo(o2)
•lambda 參數名稱不能使用 _ ,被當作保留字
java.util.function.*
•Predicate
•Function
•Supplier
•UnaryOperator
•BinaryOperator
•Optional
•etc.
Predicate
interface Predicate<T> {

boolean test(T t);

}



age -> age >= 18
!
Arrays.asList(12,25,37)

.stream()

.filter(age -> age >= 18);
Function
interface Function<T, R> {

R apply(T t);

}


title -> title.length()
!
Arrays.asList("a","b","c")

.stream()

.map(title -> title.length());
Supplier
interface Supplier<T> {

T get();

}


() -> new Random().nextInt()
!
Stream.generate(() -> 

new Random().nextInt());
UnaryOperator
interface UnaryOperator<T> extends 

Function<T,T>{
}


t -> t * 10
!
Stream.iterate(1, i -> i * 10);
BiFunction
interface BiFunction<T,U,R>{
R apply(T t, U u);
}


k, v -> v + "a"
!
map.compute(key, 

(k, v) -> (v == null) ? msg 

: v.concat(msg));
BinaryOperator
interface BinaryOperator<T> extends 

BiFunction<T,T,T>{
}


i, j -> i + j
!
Arrays.asList(12,25,37)

.stream()

.reduce(i, j -> i + j);
自己寫一個
interface Hoge {
void hogehoge();
}
!
!
•怎麼判斷自己有沒有寫對?
•加上 @FunctionalInterface,編譯時幫你
檢查是否為 Functional Interface
interface Hoge {
void hogehoge();
}
@FunctionalInterface
interface Hoge {…}
自己寫一個
•Object 的 public method 不能當唯一的抽
象方法
@FunctionalInterface
interface Hoge {
boolean equals(Object o); // compile error
}
•很多時候 lambda expression 只會呼叫一個
方法
(o1, o2) -> o1.compareTo(o2)
!
item -> item.name
!
param -> new Item(param)
Method Reference
•可以改寫的更加簡潔
!
list.stream().sorted((o1, o2) -> 

o1.compareTo(o2));
!
!
!
list.stream().sorted(String::compareTo);
•可以改寫的更加簡潔
!
list.stream().sorted((o1, o2) -> 

o1.compareTo(o2));
!
!
!
list.stream().sorted(String::compareTo);
•Static 方法
•特定物件的 Instance 方法
•特定類型的任意物件的 Instance 方法
•建構子
Method References 的種類
•Static method
class ItemTool {
static int compareByPrice(Item a, 

Item b) {

...

}
}



Arrays.asList(item1,item2,item3)

.sort(ItemTool::compareByPrice);
•特定物件的 Instance method
class ItemTool {
int compareByPrice(Item a, 

Item b) {

...

}
}
ItemTool tool = new ItemTool();

Arrays.asList(item1,item2,item3)

.sort(tool::compareByPrice);
•特定類型的任意物件的 instance method
class Item {
int compareTo(Item b) {

...

}
}


Arrays.asList(item1,item2,item3)

.sort(Item::compareTo);
•建構子
<T, R extends Collection<T>>

R copy(List<T> from, 

Supplier<R> toFactory){…}
!
List<String> sourceList = ...;
HashSet<String> result = 

copy(sourceList, HashSet::new);

class Item {
public Item() {…}
public Item(String code) {…}
}
!
interface ItemFactory {
Item create(String code);
}
!
ItemFactory factory = Item::new;
Item item = factory.create("a");
void someWork(ItemFactory factory){
Item item = factory.create("a");
…
}


someWork(Item::new);
!
!
ItemFactory factory = Item::new;
!
!
Function<String, Item> factory = 

Item::new;
Comparator<Item> comparator = 

Item::compareByPrice;
!
Comparator<Item> comparator = 

itemTool::compareByPrice;
!
Comparator<Item> comparator = 

Item::compareTo;
!
Supplier<String> factory = 

HashSet::new;
Lambda
Anonymous Class
不是
Accessing Local Variables
List<String> list = new ArrayList<>();
...
int max = 10;
list.stream().filter(

(s) -> s.length() < max

);
•不會製造新的 Scope
•this 是 enclosing class
•沒有 Shadowing 問題
•和 local class 或 anonymous class 不同
int max = 10;
list.stream().filter((s) -> {

int max = 12; // compile error

return s.length() < this.delta 

+ max;

});
//Outer$1@78308db1

Runnable r1 = new Runnable() {
@Override public void run() {
System.out.println(this);
}
}
!
//Outer@776ec8df

Runnable r2 = () -> 

System.out.println(this);
•能存取 final & effectively final 的變數
int max = 10;
final int min = 2;
list.stream().filter((s) -> {

max = 12; // compile error

return s.length() < max 

&& s.length() > min;

});
max = 15; // compile error
•Illegal forward reference
class Foo {
Runnable job = () -> {
// compile error!!

System.out.println(x);

});
int x = 10;
}
❌
•Illegal forward reference
class Foo {
Runnable job = new Runnable {
public void run(){

System.out.println(x);
}

};
int x = 10;
} ◎
(s) -> System.out.println(s)



1. void forEach(Consumer<T>)



2. void onClick(Listener)
Target Typing
•編譯器會依照 lambda expression 的所在場
合或環境的目標型態決定該 lambda
expression 的型態
@FunctionalInterface
interface Foo {
void bar(String arg);
}
// Comsumer<String>

Arrays.asList("a","b","c")

.stream()

.foreach(o -> …);
// Foo

Foo foo = o -> …;
•所以 lambda expression 必須放在編譯器可
以推斷的場合
•Variable declarations
•Assignments
•Return statements
•Array initializers
•Method or constructor arguments
•Lambda expression bodies
•Conditional expressions, ? :
•Cast expressions
void invoke(Runnable runnable);
<T> void invoke(Callable<T> callable);

// Callable<Integer>

invoke(() -> 3);
// Runnable

invoke(() -> System.out.println(3));
// ???

invoke(() -> {

while(true){ … } 

});
void invoke(Runnable runnable);
<T> void invoke(Callable<T> callable);

// Callable<Integer>

invoke(() -> 3);
// Runnable

invoke(() -> System.out.println(3));
// ???

invoke((Runnable)() -> {

while(true){ … } 

});
型推論的強化
•Java 7 的 <>
◎ List<Integer> l1 = new ArrayList<>();
❌ List<Number> l2 = new ArrayList<>(1, 

2);
❌ calculate(new ArrayList<>());
❌ List<String> result = a == 10 

? new ArrayList<>()

: Collections.emptyList();
•Java 8 的 <>
◎ List<Integer> ages = new ArrayList<>();
◎ List<Number> l2 = new ArrayList<>(1, 

2);
◎ calculate(new ArrayList<>());
◎ List<String> result = a == 10 

? new ArrayList<>()

: Collections.emptyList();
Default Methods
•幫 interface 增加新方法會造成尚未升級的實
作編譯錯誤
•例如幫 List 增加新方法,所有實作都得修
改
•連帶使利用該 API 者無法升級
•Java 8 新增了 Default Methods
•就算新增方法也能保持相容性
•實作在 interface 且會是 public 方法
•當實作類別沒有實作時會使用此預設方法
interface Foo{

…

default int sum(int a, int b){

return a + b;



}

}
class Bar implements Foo{

…
//有沒有實作都沒關係

int sum(int a, int b){

return a * b;

}

}
•lambda expression 不能呼叫預設方法
@FunctionalInterface

interface Foo{

int bar();

default int sum(int a, int b){

return a + b;

}

}



Foo foo = () -> {

return 3 + sum(1, 2); // compile error!!

};
•預設方法不能是 Object 上的方法
interface Foo{



int bar();

// compile error!!

default String toString(){

return …;

}

}
•多重繼承?
•父類別和實作的介面有一樣的方法
interface A{



default String bar(){

return …;

}

}
abstract class B{



String bar(){

return …;

}

}
class C extends B implements A{
…

}



new C().bar();
•多重繼承?
•父類別和實作的介面有一樣的方法
interface A{



default String bar(){

return …;

}

}
abstract class B{



String bar(){

return …;

}

}
class C extends B implements A{
…

}



new C().bar();//類別優先,會使用 B 的 bar
•多重繼承?
•兩個介面有一樣的方法
interface A{



default String bar(){

return …;

}

}
interface B{



default String bar(){

return …;

}

}
// Compile error!!
class C extends B, A{


}
•多重繼承?
•兩個介面有一樣的方法
interface A{



default String bar(){

return …;

}

}
interface B{



default String bar(){

return …;

}

}
// 需要自己再定義

class C extends B, A{
default String bar(){...}

}
Static interface method
•在 interface 中定義 static method
interface Foo{

static int sum(int a, int b){

return a + b;

}

}
Foo.sum(1, 2);
•不能繼承,只能透過定義的 interface 呼叫
•此點和類別中的 static method 不同
interface Bar extends Foo{

}
Bar.sum(1, 2); // compile error!!
!
class Hoge implements Foo{

}
Hoge.sum(1, 2); // compile error!!

Lambda 與 新 API
!
students.stream()
.filter( student -> student.age == 20)
.mapToInt( student -> student.score )
.max();
Stream
Optional<Bitmap> filter(Bitmap bitmap){…}
Optional<Bitmap> scale(Bitmap bitmap){…}
!
Optional<Bitmap> maybeBitmap = readFromFile(…);
maybeBitmap.flatMap(bitmap -> filter(bitmap))
.flatMap(bitmap -> scale(bitmap))
.ifPresent(bitmap -> view.setImage(bitmap));
Optional
CompletableFuture.supplyAsync(() -> …)
.thenApplyAsync((t) -> … )
.thenCompose((t) -> …)
...
CompletableFuture
Map
Map<String, List<String>> map = …;
map.computeIfAbsent("key",
o -> new ArrayList<String>())
.add("value");
Comparator
Comparator<Item> compareByPrice =
Comparator.comparing(item ->
item.price);
已知問題
public static void main(String[] args) {
Runnable r = () -> {
try {
Object o = null;
o.getClass();
throw new IOException();
} catch(IOException | IllegalArgumentException e) {
System.out.println("KO !");
} catch(RuntimeException e) {
System.out.println("OK !");
}
};
r.run();
}
http://mail.openjdk.java.net/pipermail/lambda-dev/2014-March/011940.html
Function<Integer, Integer> s1 = new 

Function<Integer, Integer>() {
@Override public Integer apply(Integer 

t) {
return t++;
}
};

Function<Integer, Integer> s2 = (t) -> t++;
!
System.out.println(s1.apply(2)); // 2
System.out.println(s2.apply(2)); // 3
https://bugs.openjdk.java.net/browse/JDK-8038420
Appendix
How lambda translated?
•Inner class
•MethodHandle
•Dynamic proxies
•...etc.
Lambda is Inner Class ?
•看來只要用 inner class 就可以實作了?
class Hoge$1 implements Consumer<String>{

private final Logger logger;

Hoge$1(Logger logger){

this.logger = logger;

}

@Override

public void accept(String t){

logger.log(t);

}

}
// Method Hoge$1."<init>":(I)V

invokespecial #3



// java/util/List.forEach:(Ljava/
util/functions/Consumer;)Z

invokeinterface #4
•如果使用 inner class,bytecode 會變成
Why not ?
•一個 lambda expression 要一個類別
•一開始就選死方法,未來如果有新實作方式該
怎麼辦 ?
MethodHandle
•與 invokedynamic 一起從 JSR-292

(Java 7 )新增
•java.util.invoke
•A reference to method(or field,
constructor or other bit of functionality)
that can be executed
MethodHandle
•把 lambda expression 轉換成方法
•在 bytecode 中把 lambda 轉換成
MethodHandle
stream.filter(item -> 

item.getPrice() > 10);
!
!
private static boolean lambda$1(Item item)

{

return item.getPrice() > 10;

}
!
MethodHandle mh = LDC[lambda$1];
stream.filter(mh);
Why not ?
•Stream#filter 的參數變成 MethodHandle
•Overloading 怎麼辦 ?
•型態資 還是得找地方放
•MH 會有比較好的效能 ?
•未來如果有更好的實作方式該怎辦 ?
invokedynamic
•From JSR-292
•為了 JRuby 等 JVM 上的其他語言而出現
•可以動態決定要呼叫的實體
invokedynamic
Client
Bootstrap Callsite
MethodHandle Target Method
Client
Bootstrap CallSite
MethodHandle Target Method
private static void printArgs(Object... args) {

System.out.println(Arrays.deepToString(args));

}
Client
Bootstrap CallSite
MethodHandle Target Method
InvokeDynamic[#bootstrapDynamic].baz("baz arg", 2, 3.14);
private static CallSite bootstrapDynamic( 

MethodHandles.Lookup caller, 

String name, 

MethodType type)
Client
Bootstrap CallSite
MethodHandle Target Method
MethodHandles.Lookup lookup = MethodHandles.lookup();
return new ConstantCallSite(

lookup.findStatic(Hoge.class, "printArgs", 

MethodType

.methodType(void.class, Object[].class)

.asType(type));
透過 indy 轉換 lambda
•將 lambda 轉換成和 functional interface
相同 signature 的方法(依情況爲靜態或非靜
態)







item -> item.getPrice() > 10
!


private static boolean lambda$1(Item item)
{

return item.getPrice() > 10;

}
•產生 indy call site,呼叫時回傳 lambda,
也就是 lambda factory







item -> item.getPrice() > 10
!
!
Predicate $p = 

indy[bootstrap=LambdaMetafactory, 

staticargs=[Predicate, lambda$1])
stream.filter($p);
•Bootstrap 選擇轉換策略來建立 lambda
factory
• 裡的 Bootstrap 被稱為 lambda
metafactory
•因為是提供的類別,所以爲 runtime 的一
部份
轉換策略
•Runtime 時產生 inner class
•就像之前編譯器產生的一樣,裡面透過
invokestatic 和 invokevirtual 直接呼叫 lambda
產生的方法
•Runtime 時依照 interface 建立 wrapper class
•建構子傳入MH
•Dynamic proxies or MH proxy
•VM private api, or ...
透過 indy 的好處
•延遲到第一次使用時才產生和存取需要的類別
•因為延遲初始和間接產生,例如無狀態(沒有
抓取變數)的 lambda 可以使用同一個實體
•對效能有幫助
•未來還能切換實作方式

More Related Content

What's hot

Java SE 8 的 Lambda 連鎖效應 - 語法、風格與程式庫
Java SE 8 的 Lambda 連鎖效應 - 語法、風格與程式庫Java SE 8 的 Lambda 連鎖效應 - 語法、風格與程式庫
Java SE 8 的 Lambda 連鎖效應 - 語法、風格與程式庫Justin Lin
 
深入淺出 Web 容器 - Tomcat 原始碼分析
深入淺出 Web 容器  - Tomcat 原始碼分析深入淺出 Web 容器  - Tomcat 原始碼分析
深入淺出 Web 容器 - Tomcat 原始碼分析Justin Lin
 
The Evolution of Async Programming (GZ TechParty C#)
The Evolution of Async Programming (GZ TechParty C#)The Evolution of Async Programming (GZ TechParty C#)
The Evolution of Async Programming (GZ TechParty C#)jeffz
 
Wind.js无障碍调试与排错
Wind.js无障碍调试与排错Wind.js无障碍调试与排错
Wind.js无障碍调试与排错jeffz
 
ES5 introduction
ES5 introductionES5 introduction
ES5 introductionotakustay
 
Javascript share
Javascript shareJavascript share
Javascript shareXu Mac
 
Sigreturn Oriented Programming
Sigreturn Oriented ProgrammingSigreturn Oriented Programming
Sigreturn Oriented ProgrammingAngel Boy
 
所谓闭包
所谓闭包所谓闭包
所谓闭包youzitang
 
Python learn guide
Python learn guidePython learn guide
Python learn guiderobin yang
 
Keep your code clean
Keep your code cleanKeep your code clean
Keep your code cleanmacrochen
 
Return to dlresolve
Return to dlresolveReturn to dlresolve
Return to dlresolveAngel Boy
 
所谓闭包
所谓闭包所谓闭包
所谓闭包ilovey4
 
C python 原始碼解析 投影片
C python 原始碼解析 投影片C python 原始碼解析 投影片
C python 原始碼解析 投影片kao kuo-tung
 
Java 8 與 retrolambda
Java 8 與 retrolambdaJava 8 與 retrolambda
Java 8 與 retrolambdaJustin Lin
 

What's hot (20)

Java SE 8 的 Lambda 連鎖效應 - 語法、風格與程式庫
Java SE 8 的 Lambda 連鎖效應 - 語法、風格與程式庫Java SE 8 的 Lambda 連鎖效應 - 語法、風格與程式庫
Java SE 8 的 Lambda 連鎖效應 - 語法、風格與程式庫
 
深入淺出 Web 容器 - Tomcat 原始碼分析
深入淺出 Web 容器  - Tomcat 原始碼分析深入淺出 Web 容器  - Tomcat 原始碼分析
深入淺出 Web 容器 - Tomcat 原始碼分析
 
Scala
ScalaScala
Scala
 
The Evolution of Async Programming (GZ TechParty C#)
The Evolution of Async Programming (GZ TechParty C#)The Evolution of Async Programming (GZ TechParty C#)
The Evolution of Async Programming (GZ TechParty C#)
 
Hi Haskell
Hi HaskellHi Haskell
Hi Haskell
 
Execution
ExecutionExecution
Execution
 
Wind.js无障碍调试与排错
Wind.js无障碍调试与排错Wind.js无障碍调试与排错
Wind.js无障碍调试与排错
 
ES5 introduction
ES5 introductionES5 introduction
ES5 introduction
 
Ooredis
OoredisOoredis
Ooredis
 
Javascript share
Javascript shareJavascript share
Javascript share
 
Scala+RDD
Scala+RDDScala+RDD
Scala+RDD
 
Sigreturn Oriented Programming
Sigreturn Oriented ProgrammingSigreturn Oriented Programming
Sigreturn Oriented Programming
 
所谓闭包
所谓闭包所谓闭包
所谓闭包
 
Python learn guide
Python learn guidePython learn guide
Python learn guide
 
Keep your code clean
Keep your code cleanKeep your code clean
Keep your code clean
 
Return to dlresolve
Return to dlresolveReturn to dlresolve
Return to dlresolve
 
所谓闭包
所谓闭包所谓闭包
所谓闭包
 
Linq 入门
Linq 入门Linq 入门
Linq 入门
 
C python 原始碼解析 投影片
C python 原始碼解析 投影片C python 原始碼解析 投影片
C python 原始碼解析 投影片
 
Java 8 與 retrolambda
Java 8 與 retrolambdaJava 8 與 retrolambda
Java 8 與 retrolambda
 

Viewers also liked

Java8 stream
Java8 streamJava8 stream
Java8 streamkoji lin
 
CEE HRM Skills Workshop on Emotional Quotient (EQ) for Workplace Success - 25...
CEE HRM Skills Workshop on Emotional Quotient (EQ) for Workplace Success - 25...CEE HRM Skills Workshop on Emotional Quotient (EQ) for Workplace Success - 25...
CEE HRM Skills Workshop on Emotional Quotient (EQ) for Workplace Success - 25...Centre for Executive Education
 
Linux firewall-201503
Linux firewall-201503Linux firewall-201503
Linux firewall-201503Kenduest Lee
 
Economic efficiency
Economic efficiencyEconomic efficiency
Economic efficiencyaseldis
 
Academic freedom ppt
Academic freedom pptAcademic freedom ppt
Academic freedom pptPenn State
 
What Is Emotional Intelligence?
What Is Emotional Intelligence?What Is Emotional Intelligence?
What Is Emotional Intelligence?taylor_keele
 

Viewers also liked (8)

Java8 stream
Java8 streamJava8 stream
Java8 stream
 
Consumer surplus
Consumer surplusConsumer surplus
Consumer surplus
 
Consumer surplus
Consumer surplusConsumer surplus
Consumer surplus
 
CEE HRM Skills Workshop on Emotional Quotient (EQ) for Workplace Success - 25...
CEE HRM Skills Workshop on Emotional Quotient (EQ) for Workplace Success - 25...CEE HRM Skills Workshop on Emotional Quotient (EQ) for Workplace Success - 25...
CEE HRM Skills Workshop on Emotional Quotient (EQ) for Workplace Success - 25...
 
Linux firewall-201503
Linux firewall-201503Linux firewall-201503
Linux firewall-201503
 
Economic efficiency
Economic efficiencyEconomic efficiency
Economic efficiency
 
Academic freedom ppt
Academic freedom pptAcademic freedom ppt
Academic freedom ppt
 
What Is Emotional Intelligence?
What Is Emotional Intelligence?What Is Emotional Intelligence?
What Is Emotional Intelligence?
 

Similar to Java8 lambda

Study4.TW .NET Conf 2018 - Fp in c#
Study4.TW .NET Conf 2018  - Fp in c#Study4.TW .NET Conf 2018  - Fp in c#
Study4.TW .NET Conf 2018 - Fp in c#Chieh Kai Yang
 
12, string
12, string12, string
12, stringted-xu
 
J2ee面试知识
J2ee面试知识J2ee面试知识
J2ee面试知识yiditushe
 
走马观花— Haskell Web 开发
走马观花— Haskell Web 开发走马观花— Haskell Web 开发
走马观花— Haskell Web 开发Gump Law
 
Java华为面试题
Java华为面试题Java华为面试题
Java华为面试题yiditushe
 
twMVC#46_SQL Server 資料分析大躍進 Machine Learning Services
twMVC#46_SQL Server 資料分析大躍進 Machine Learning ServicestwMVC#46_SQL Server 資料分析大躍進 Machine Learning Services
twMVC#46_SQL Server 資料分析大躍進 Machine Learning ServicestwMVC
 
千呼萬喚始出來的Java SE 7
千呼萬喚始出來的Java SE 7千呼萬喚始出來的Java SE 7
千呼萬喚始出來的Java SE 7javatwo2011
 
神州泰岳测试试题(笔试)
神州泰岳测试试题(笔试)神州泰岳测试试题(笔试)
神州泰岳测试试题(笔试)yiditushe
 
Node.js开发体验
Node.js开发体验Node.js开发体验
Node.js开发体验QLeelulu
 
炎炎夏日學 Android 課程 - Part1: Kotlin 語法介紹
炎炎夏日學 Android 課程 -  Part1: Kotlin 語法介紹炎炎夏日學 Android 課程 -  Part1: Kotlin 語法介紹
炎炎夏日學 Android 課程 - Part1: Kotlin 語法介紹Johnny Sung
 
About closure
About closureAbout closure
About closureotakustay
 
Java Jdk6学习笔记[Ppt]
Java Jdk6学习笔记[Ppt]Java Jdk6学习笔记[Ppt]
Java Jdk6学习笔记[Ppt]yiditushe
 
cppcheck源码分析
cppcheck源码分析cppcheck源码分析
cppcheck源码分析Wu Liang
 
Python 脚本入门基础
Python 脚本入门基础Python 脚本入门基础
Python 脚本入门基础wklken
 

Similar to Java8 lambda (20)

Python 温故
Python 温故Python 温故
Python 温故
 
functional-scala
functional-scalafunctional-scala
functional-scala
 
Scala+spark 2nd
Scala+spark 2ndScala+spark 2nd
Scala+spark 2nd
 
Sun java
Sun javaSun java
Sun java
 
Study4.TW .NET Conf 2018 - Fp in c#
Study4.TW .NET Conf 2018  - Fp in c#Study4.TW .NET Conf 2018  - Fp in c#
Study4.TW .NET Conf 2018 - Fp in c#
 
Ooredis
OoredisOoredis
Ooredis
 
12, string
12, string12, string
12, string
 
J2ee面试知识
J2ee面试知识J2ee面试知识
J2ee面试知识
 
走马观花— Haskell Web 开发
走马观花— Haskell Web 开发走马观花— Haskell Web 开发
走马观花— Haskell Web 开发
 
Java华为面试题
Java华为面试题Java华为面试题
Java华为面试题
 
twMVC#46_SQL Server 資料分析大躍進 Machine Learning Services
twMVC#46_SQL Server 資料分析大躍進 Machine Learning ServicestwMVC#46_SQL Server 資料分析大躍進 Machine Learning Services
twMVC#46_SQL Server 資料分析大躍進 Machine Learning Services
 
千呼萬喚始出來的Java SE 7
千呼萬喚始出來的Java SE 7千呼萬喚始出來的Java SE 7
千呼萬喚始出來的Java SE 7
 
神州泰岳测试试题(笔试)
神州泰岳测试试题(笔试)神州泰岳测试试题(笔试)
神州泰岳测试试题(笔试)
 
Node.js开发体验
Node.js开发体验Node.js开发体验
Node.js开发体验
 
Glider
GliderGlider
Glider
 
炎炎夏日學 Android 課程 - Part1: Kotlin 語法介紹
炎炎夏日學 Android 課程 -  Part1: Kotlin 語法介紹炎炎夏日學 Android 課程 -  Part1: Kotlin 語法介紹
炎炎夏日學 Android 課程 - Part1: Kotlin 語法介紹
 
About closure
About closureAbout closure
About closure
 
Java Jdk6学习笔记[Ppt]
Java Jdk6学习笔记[Ppt]Java Jdk6学习笔记[Ppt]
Java Jdk6学习笔记[Ppt]
 
cppcheck源码分析
cppcheck源码分析cppcheck源码分析
cppcheck源码分析
 
Python 脚本入门基础
Python 脚本入门基础Python 脚本入门基础
Python 脚本入门基础
 

More from koji lin

サーバーサイドでの非同期処理で色々やったよ
サーバーサイドでの非同期処理で色々やったよサーバーサイドでの非同期処理で色々やったよ
サーバーサイドでの非同期処理で色々やったよkoji lin
 
Using armeria to write your RPC
Using armeria to write your RPCUsing armeria to write your RPC
Using armeria to write your RPCkoji lin
 
使用 Java 上的 future/promise API
使用 Java 上的 future/promise  API使用 Java 上的 future/promise  API
使用 Java 上的 future/promise APIkoji lin
 
Annotation processing and code gen
Annotation processing and code genAnnotation processing and code gen
Annotation processing and code genkoji lin
 
docker intro
docker introdocker intro
docker introkoji lin
 
Java8 time
Java8 timeJava8 time
Java8 timekoji lin
 
CompletableFuture
CompletableFutureCompletableFuture
CompletableFuturekoji lin
 
Raspberry Pi with Java
Raspberry Pi with JavaRaspberry Pi with Java
Raspberry Pi with Javakoji lin
 
Services you can use to monitor and analyze mobile app
Services you can use to monitor and analyze mobile appServices you can use to monitor and analyze mobile app
Services you can use to monitor and analyze mobile appkoji lin
 
Programming with Threads in Java
Programming with Threads in JavaProgramming with Threads in Java
Programming with Threads in Javakoji lin
 
山頂洞人日記 - 回歸到最純樸的開發
山頂洞人日記 -  回歸到最純樸的開發山頂洞人日記 -  回歸到最純樸的開發
山頂洞人日記 - 回歸到最純樸的開發koji lin
 
Android Location-based應用開發分享
Android Location-based應用開發分享Android Location-based應用開發分享
Android Location-based應用開發分享koji lin
 

More from koji lin (16)

サーバーサイドでの非同期処理で色々やったよ
サーバーサイドでの非同期処理で色々やったよサーバーサイドでの非同期処理で色々やったよ
サーバーサイドでの非同期処理で色々やったよ
 
G1GC
G1GCG1GC
G1GC
 
Using armeria to write your RPC
Using armeria to write your RPCUsing armeria to write your RPC
Using armeria to write your RPC
 
使用 Java 上的 future/promise API
使用 Java 上的 future/promise  API使用 Java 上的 future/promise  API
使用 Java 上的 future/promise API
 
Annotation processing and code gen
Annotation processing and code genAnnotation processing and code gen
Annotation processing and code gen
 
Jcconf
JcconfJcconf
Jcconf
 
docker intro
docker introdocker intro
docker intro
 
Java8 time
Java8 timeJava8 time
Java8 time
 
Idea13
Idea13Idea13
Idea13
 
CompletableFuture
CompletableFutureCompletableFuture
CompletableFuture
 
Raspberry Pi with Java
Raspberry Pi with JavaRaspberry Pi with Java
Raspberry Pi with Java
 
Services you can use to monitor and analyze mobile app
Services you can use to monitor and analyze mobile appServices you can use to monitor and analyze mobile app
Services you can use to monitor and analyze mobile app
 
Programming with Threads in Java
Programming with Threads in JavaProgramming with Threads in Java
Programming with Threads in Java
 
JQuery
JQueryJQuery
JQuery
 
山頂洞人日記 - 回歸到最純樸的開發
山頂洞人日記 -  回歸到最純樸的開發山頂洞人日記 -  回歸到最純樸的開發
山頂洞人日記 - 回歸到最純樸的開發
 
Android Location-based應用開發分享
Android Location-based應用開發分享Android Location-based應用開發分享
Android Location-based應用開發分享
 

Java8 lambda