Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
忙しい人のための Functional Programming in Java / Funct...
Search
Youhei Nitta
November 14, 2014
Programming
950
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
忙しい人のための Functional Programming in Java / Functional Programming in Java for business person
社内勉強会でサンプルコードをベースに「Javaによる関数型プログラミング」の簡単なふりかえりをしました.
喋りで補ったところが多いかも...
Youhei Nitta
November 14, 2014
More Decks by Youhei Nitta
See All by Youhei Nitta
実践 Git / Pragmatic Git
youhei
2
210
Other Decks in Programming
See All in Programming
標準パッケージに uuid が追加された 背景から見る Go らしい意思決定 / go_127_uuid_decision
convto
5
6.8k
型解析で実現する Go の言語内 DSL / Conference に Go! タイムテーブルの歩き方 for Gophers
mazrean
0
150
海上で動くGoサーバー: goroutineとchannelでさばく航行データストリーム
atsuki_seo
0
330
世界の中心で、AI(App Intents)をさけぶ ー App Intents中心設計の実践ガイド
touyou
0
540
[DroidKaigi 2026] Bring your own phones to Gradle Managed Devices
f2lk
0
120
Go × SIMDで高速化するベクトル検索 ~ルーフラインモデルでSIMDが効く境界を探れ! ~
po3rin
1
560
Snowflakeで業務アプリを作ろう。 Snowflakeのアプリ機能解説&実践ガイド
ayumu_yamaguchi
1
270
The Good Stuff, Not the Slop: Engineering High-Quality Android Apps with Modern AI Tooling
danybony
1
250
数年滞っていたダークモード対応をおよそ2週間で完了させる
chigichan24
0
710
TiDB Cloudのカスタムコントローラーによるオートスケール対応
takaidohigasi
0
110
Security issues being discussed on Web Platforms
petamoriken
0
890
自分的「カンファレンスの楽しみ方」
syumai
0
200
Featured
See All Featured
Abbi's Birthday
coloredviolet
3
10k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
4.8k
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
500
Highjacked: Video Game Concept Design
rkendrick25
PRO
1
460
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
410
sira's awesome portfolio website redesign presentation
elsirapls
0
410
Everyday Curiosity
cassininazir
0
320
What's in a price? How to price your products and services
michaelherold
247
13k
The Limits of Empathy - UXLibs8
cassininazir
1
660
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
440
Getting science done with accelerated Python computing platforms
jacobtomlinson
2
480
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
520
Transcript
@youhei Software Engineer Fri Nov 14 © 2014 Youhei Nitta,
All rights reserved. Redistribution or public display not permitted without written permission from Youhei Nitta. ͍͠ਓͷͨΊͷ Functional Programming in Java
Java ʹΑΔؔܕϓϩάϥϛϯά Java 8 ϥϜμࣜͱ Stream ಡΈ·ͨ͠ɻ ྑॻͩͬͨͷͰɺखʹৼΓ ฦͬͯΈ·͢ɻ
ैདྷͷํ๏ public static void main(final String[] args) {! BigDecimal totalOfDiscountedPrices
= BigDecimal.ZERO;! ! for(BigDecimal price : prices) {! if(price.compareTo(BigDecimal.valueOf(20)) > 0) ! totalOfDiscountedPrices = ! totalOfDiscountedPrices.add(price.multiply(BigDecimal.valueOf(0.9)));! }! System.out.println("Total of discounted prices: " + totalOfDiscountedPrices);! } ໋ྩܕελΠϧ ͲͷΑ͏ʹ࣮ߦͯ͠ཉ͍͔͠Λهड़ mutable ͳมΛѻ͍ͬͯΔ
Java 8 public static void main(final String[] args) {! final
BigDecimal totalOfDiscountedPrices = ! prices.stream()! .filter(price -> price.compareTo(BigDecimal.valueOf(20)) > 0)! .map(price -> price.multiply(BigDecimal.valueOf(0.9)))! .reduce(BigDecimal.ZERO, BigDecimal::add);! ! System.out.println("Total of discounted prices: " + totalOfDiscountedPrices);! } ؔܕελΠϧ ྲྀΕΔΑ͏ʹॲཧΛॻ͘ (Stream API) ԿΛ࣮ߦ͖͔͢Λهड़ ࠶ೖΛճආ͍ͯ͠Δ
ͳͥؔܕΛ͏ͷ͔ • એݴతͰಡΈ͍͢ • ෆมੑʹΑΓόάΛࠞೖ͠ʹ͍͘ • ฒྻԽ͕༰қ • ԆධՁʹΑΓޮత
Java 8 ϥϜμࣜ
Java 8 ͷϥϜμࣜͷϙΠϯτ ୯ҰϝιουΠϯλϑΣʔε (Comparable, Runnable ͳͲ) ͷಗ໊ΫϥεͷΠϯελϯεΛ͢ɺͱ͍͏ݩʑ ͋ͬͨίϯηϓτΛ֦ுͨ͠ɻ ܰྔͳه๏ͱͯ͠ϥϜμࣜΛಋೖ͠ɺ͔͋ͨؔΛ
͍ͯ͠ΔΑ͏ʹݟͤͯɺ࣮୯Ұϝιουಗ໊Ϋϥεͷ ΠϯελϯεΛ͍ͯ͠Δɻ طଘͷ JDK ϥΠϒϥϦʹޓੑΛͭͷ͕རɻ
ಗ໊ΫϥεͷΠϯελϯε friends.forEach(new Consumer<String>() {! public void accept(final String name) {!
System.out.println(name);! }! }); Java 7 Ҏલͷจ๏ʹԊͬͨه๏ɻ Iterable ͷ forEach ϝιουʹ Consumer ಗ໊Ϋϥεͷ ΠϯελϯεΛ͍ͯ͠Δɻ
ϥϜμࣜ ! //ॲཧ͕1ߦͩͱίʔυϒϩοΫͷׅހলུՄɻҾʹ final Λ໌ࣔͰ͖Δɻ! friends.forEach((final String name) -> System.out.println(name));!
//ܕਪͰҾͷܕએݴΛলུՄɻ! friends.forEach((name) -> System.out.println(name));! //Ҿ͕1ݸͩͱׅހΛলུՄɻ! friends.forEach(name -> System.out.println(name)); ϥϜμࣜҥߏจɻ ίϯύΠϥ͕߹ϝιουΛੜ͍ͯ͠Δɻ ※ ࣮ґଘ͕ͩಗ໊ΫϥεͷΠϯελϯεੜͷҥߏจͰͳ͘ɺinvokedynamic Ͱ࣮ߦ࣌ʹಗ໊ΫϥεΛੜ͢Δॲཧʹஔ͖ΘΔɻΫϥεϑΝΠϧΛ࡞Βͤͳ͍ͨΊɻ
ϝιουࢀর //Ҿলུ! friends.forEach(System.out::println); ϝιουͷ໊લΛ͢ͷͰՄಡੑ͕ߴ͍ɻ ϝιουࢀরҾΛิ͠ίϯύΠϥ͕߹ϝιουʹ ม͍ͯ͠Δɻ
࣮ࡍʹͬͯΈͯ ଞͷݴޠͷϥϜμࣜͱ༻ײ͕ҧͬͨɻ API Λఏڙ͢Δଆ͔ΒΈͯҧ͍͕ͳ͍ɻ ! API ར༻ଆͷࢹ: ؔʢϥϜμࣜɾϝιουࢀরʣΛҾʹ͍ͯ͠Δ ! API
ఏڙଆͷࢹ: Ҿʹ͜Ε·Ͱ௨ΓͷΠϯελϯεΛड͚औ͍ͬͯΔ
Strategy Pattern
Predicate<T> ͰϩδοΫΛ͚Δ ! public static int totalAssetValues(final List<Asset> assets,! final
Predicate<Asset> assetSelector) {! return assets.stream()! .filter(assetSelector)! .mapToInt(Asset::getValue)! .sum();! }! ! //! totalAssetValues(assets, asset -> true);! totalAssetValues(assets, asset -> asset.getType() == AssetType.BOND));! totalAssetValues(assets, asset -> asset.getType() == AssetType.STOCK));! Strategy Pattern ͰϩδοΫΛൈ͖ग़͍ͯ͠Δɻ ࠓ·Ͱ৽͍͠ΫϥεΛ༻ҙ͍͕ͯͨ͠ɺϥϜμࣜͰදݱͰ͖ΔΑ͏ʹͳͬͨɻ ؔܕʹ׳Ε͍ͯΔͱී௨ͷύλʔϯ͚ͩͲɺJava Ͱॻ͚ΔΑ͏ʹͳͬͨɻ
Decorator Pattern
Stream API Ͱ࣍ʑʹద༻͢Δ public class Camera { ! private Function<Color,
Color> filter;! ! public void setFilters(final Function<Color, Color>... filters) {! filter = ! Stream.of(filters)! .reduce((filter, next) -> filter.compose(next))! .orElse(color -> color);! //.orElseGet(Function::identity); Ͱಉ͡! }! }! ! camera.setFilters(Color::brighter);! camera.setFilters(Color::darker);! camera.setFilters(Color::brighter, Color::darker); Decorator ύλʔϯɻΫϥεΛೖΕࢠʹͤͣ Stream API Ͱద༻ͨ݁͠ՌΛฦ͢ɻ ΫϥεΛఆٛͯ͠ೖΕࢠʹ͢Δख͕ؒল͚Δɻ දྫ. new BufferedReader(new InputStreamReader(is, "UTF-8"));
Execute Around Method Pattern
try-finally ͷϦιʔεղ์ public static void main(final String[] args) throws IOException
{! final FileWriterExample writerExample = ! new FileWriterExample("peekaboo.txt");! try {! writerExample.writeStuff("peek-a-boo"); ! } finally {! writerExample.close(); ! }! } యܕతͳύλʔϯ͕ͩɺίʔυ͕ࡶʹͳΔɻ ྫ֎ॲཧΛͪΌΜͱΔͱߋʹɻɻ
try-with-resources ͷϦιʔεཧ public static void main(final String[] args) throws IOException
{! try(final FileWriterARM writerARM = new FileWriterARM("peekaboo.txt")) {! writerARM.writeStuff("peek-a-boo");! ! ! System.out.println("done with the resource...");! }! } Java 7 ͔Βಋೖ͞Εͨɻ AutoCloseable ࣮ΫϥεͰ͋Δඞཁ͕͋Δɻ ։ൃऀ͕ AutoCloseable ͷ࣮Λ࣮֬ʹߦ͍ɺtry-with-resources ΛΕͣʹΘ ͳ͍ͱ͍͚ͳ͍ɻ
Execute Around Method Pattern public static void use(final String fileName,
! // UseInstance accept(T instance) throws X; Λͭ FunctionalInterface! final UseInstance<FileWriterEAM, IOException> block) throws IOException {! ! final FileWriterEAM writerEAM = new FileWriterEAM(fileName); ! try {! block.accept(writerEAM);! } finally {! writerEAM.close();! }! }! ! public static void main(final String[] args) throws IOException {! ! FileWriterEAM.use("eam2.txt", writerEAM -> {! writerEAM.writeStuff("how");! writerEAM.writeStuff("sweet"); ! });! }! } ϥϜμࣜΛ͏ɻ API Λ༻͢ΔਓʹϦιʔεཧΛҙࣝͤ͞ͳ͍ɻ JDBC ͷτϥϯβΫγϣϯཧɺLock ͷཧʹԠ༻Ͱ͖Δɻ
Virtual Proxy Pattern
ॳظԽͷԆ public class HolderNaive {! private Heavy heavy;! ! public
Heavy getHeavy() {! if(heavy == null) {! heavy = new Heavy();! }! ! return heavy;! }! }! ͓ͳ͡Έͷॲཧ͚ͩͲɺ৭ʑରॲ͖͕͋͢Δɻ
εϨουηʔϑ public class HolderThreadSafe {! private Heavy heavy;! ! public
synchronized Heavy getHeavy() {! if(heavy == null) {! heavy = new Heavy();! }! ! return heavy;! }! ! } ڝ߹ঢ়ଶΛഉআͨ͠ɻ εϨουͷ༗ແʹؔΘΒͣϝϞϦόϦΞΛ͑ͳ͚Ε͍͚ͳ͍ɻ ڝ߹͕ʹͳΔͷ࠷ॳ͚ͩɻ
Virtual Proxy Pattern ! public class Holder {! private Supplier<Heavy>
heavy = () -> createAndCacheHeavy();! ! public Heavy getHeavy() {! return heavy.get();! }! ! ϥϜμࣜͷϑΝΫτϦʔΫϥεΛఆٛͯ͠ɺ࠷ॳ͚ͩڝ߹ঢ়ଶʹରॲ͍ͯ͠Δɻ ೋճҎ߱ϑΝΫτϦʔΫϥεΛࠩ͠ସ͑ͯ synchronized ௨Βͣ୯७ʹΠϯελ ϯεΛฦ͢ɻैདྷ͋ͬͨ null νΣοΫͳ͘ͳͬͨɻ private synchronized Heavy createAndCacheHeavy() {! class HeavyFactory implements Supplier<Heavy> {! private final Heavy heavyInstance = new Heavy();! ! public Heavy get() { return heavyInstance; }! }! ! if(!HeavyFactory.class.isInstance(heavy)) {! heavy = new HeavyFactory();! }! ! return heavy.get();! }! ! }
Conclusion
Java ʹΑΔؔܕϓϩάϥϛϯά Java 8 ϥϜμࣜͱ Stream ଞʹϥϜμࣜͷ͑ΔςΫχοΫ͕ͨ͘͞ Μࡌ͍ͬͯ·͢ʢແݶϦετɺ࠶ؼݺͼग़͠ ࠷దԽͳͲʣɻ ࠓճ
Stream API ʹ͍ͭͯେ෯ʹলུͯ͠ ͍·͕͢ɺͦͪΒ͔ͬ͠Γ͓͍͑ͯ͞·͢ɻ ! ʮ࣌ Java!ʯͳͷͰങ͍!!