Slide 1

Slide 1 text

@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

Slide 2

Slide 2 text

Java ʹΑΔؔ਺ܕϓϩάϥϛϯά Java 8 ϥϜμࣜͱ Stream ಡΈ·ͨ͠ɻ ྑॻͩͬͨͷͰɺख୹ʹৼΓ ฦͬͯΈ·͢ɻ

Slide 3

Slide 3 text

ैདྷͷํ๏ 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 ͳม਺Λѻ͍ͬͯΔ

Slide 4

Slide 4 text

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) ԿΛ࣮ߦ͢΂͖͔Λهड़ ࠶୅ೖΛճආ͍ͯ͠Δ

Slide 5

Slide 5 text

ͳͥؔ਺ܕΛ࢖͏ͷ͔ • એݴతͰಡΈ΍͍͢ • ෆมੑʹΑΓόάΛࠞೖ͠ʹ͍͘ • ฒྻԽ͕༰қ • ஗ԆධՁʹΑΓޮ཰త

Slide 6

Slide 6 text

Java 8 ϥϜμࣜ

Slide 7

Slide 7 text

Java 8 ͷϥϜμࣜͷϙΠϯτ ୯ҰϝιουΠϯλϑΣʔε (Comparable, Runnable ͳͲ) ͷಗ໊ΫϥεͷΠϯελϯεΛ౉͢ɺͱ͍͏ݩʑ ͋ͬͨίϯηϓτΛ֦ுͨ͠ɻ ܰྔͳه๏ͱͯ͠ϥϜμࣜΛಋೖ͠ɺ͔͋ͨ΋ؔ਺Λ౉ ͍ͯ͠ΔΑ͏ʹݟͤͯɺ࣮͸୯Ұϝιουಗ໊Ϋϥεͷ ΠϯελϯεΛ౉͍ͯ͠Δɻ طଘͷ JDK ϥΠϒϥϦʹ΋ޓ׵ੑΛ΋ͭͷ͕ར఺ɻ

Slide 8

Slide 8 text

ಗ໊ΫϥεͷΠϯελϯε friends.forEach(new Consumer() {! public void accept(final String name) {! System.out.println(name);! }! }); Java 7 Ҏલͷจ๏ʹԊͬͨه๏ɻ Iterable ͷ forEach ϝιουʹ Consumer ಗ໊Ϋϥεͷ ΠϯελϯεΛ౉͍ͯ͠Δɻ

Slide 9

Slide 9 text

ϥϜμࣜ ! //ॲཧ͕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 Ͱ࣮ߦ࣌ʹಗ໊ΫϥεΛੜ੒͢Δॲཧʹஔ͖׵ΘΔɻΫϥεϑΝΠϧΛ࡞Βͤͳ͍ͨΊɻ

Slide 10

Slide 10 text

ϝιουࢀর //Ҿ਺΋লུ! friends.forEach(System.out::println); ϝιουͷ໊લΛ௚઀౉͢ͷͰՄಡੑ͕ߴ͍ɻ ϝιουࢀর΋Ҿ਺Λิ׬͠ίϯύΠϥ͕߹੒ϝιουʹ ม׵͍ͯ͠Δɻ

Slide 11

Slide 11 text

࣮ࡍʹ࢖ͬͯΈͯ ଞͷݴޠͷϥϜμࣜͱ͸࢖༻ײ͕ҧͬͨɻ API Λఏڙ͢Δଆ͔ΒΈͯҧ͍͕ͳ͍ɻ ! API ར༻ଆͷࢹ఺: ؔ਺ʢϥϜμࣜɾϝιουࢀরʣΛҾ਺ʹ౉͍ͯ͠Δ ! API ఏڙଆͷࢹ఺: Ҿ਺ʹ͜Ε·Ͱ௨ΓͷΠϯελϯεΛड͚औ͍ͬͯΔ

Slide 12

Slide 12 text

Strategy Pattern

Slide 13

Slide 13 text

Predicate ͰϩδοΫΛ෼͚Δ ! public static int totalAssetValues(final List assets,! final Predicate 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 Ͱ΋ॻ͚ΔΑ͏ʹͳͬͨɻ

Slide 14

Slide 14 text

Decorator Pattern

Slide 15

Slide 15 text

Stream API Ͱ࣍ʑʹద༻͢Δ public class Camera { ! private Function filter;! ! public void setFilters(final Function... 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"));

Slide 16

Slide 16 text

Execute Around Method Pattern

Slide 17

Slide 17 text

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(); ! }! } యܕతͳύλʔϯ͕ͩɺίʔυ͕൥ࡶʹͳΔɻ ྫ֎ॲཧΛͪΌΜͱ΍Δͱߋʹɻɻ

Slide 18

Slide 18 text

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 Λ๨Εͣʹ࢖Θ ͳ͍ͱ͍͚ͳ͍ɻ

Slide 19

Slide 19 text

Execute Around Method Pattern public static void use(final String fileName, ! // UseInstance ͸ accept(T instance) throws X; Λ΋ͭ FunctionalInterface! final UseInstance 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 ͷ؅ཧʹ΋Ԡ༻Ͱ͖Δɻ

Slide 20

Slide 20 text

Virtual Proxy Pattern

Slide 21

Slide 21 text

ॳظԽͷ஗Ԇ public class HolderNaive {! private Heavy heavy;! ! public Heavy getHeavy() {! if(heavy == null) {! heavy = new Heavy();! }! ! return heavy;! }! }! ͓ͳ͡Έͷॲཧ͚ͩͲɺ৭ʑରॲ͢΂͖໰୊͕͋Δɻ

Slide 22

Slide 22 text

εϨουηʔϑ public class HolderThreadSafe {! private Heavy heavy;! ! public synchronized Heavy getHeavy() {! if(heavy == null) {! heavy = new Heavy();! }! ! return heavy;! }! ! } ڝ߹ঢ়ଶΛഉআͨ͠ɻ εϨουͷ༗ແʹؔΘΒͣϝϞϦόϦΞΛ௒͑ͳ͚Ε͹͍͚ͳ͍ɻ ڝ߹͕໰୊ʹͳΔͷ͸࠷ॳ͚ͩɻ

Slide 23

Slide 23 text

Virtual Proxy Pattern ! public class Holder {! private Supplier heavy = () -> createAndCacheHeavy();! ! public Heavy getHeavy() {! return heavy.get();! }! ! ϥϜμࣜͷϑΝΫτϦʔΫϥεΛఆٛͯ͠ɺ࠷ॳ͚ͩڝ߹ঢ়ଶʹରॲ͍ͯ͠Δɻ ೋճ໨Ҏ߱͸ϑΝΫτϦʔΫϥεΛࠩ͠ସ͑ͯ synchronized ͸௨Βͣ୯७ʹΠϯελ ϯεΛฦ͢ɻैདྷ͋ͬͨ null νΣοΫ΋ͳ͘ͳͬͨɻ private synchronized Heavy createAndCacheHeavy() {! class HeavyFactory implements Supplier {! private final Heavy heavyInstance = new Heavy();! ! public Heavy get() { return heavyInstance; }! }! ! if(!HeavyFactory.class.isInstance(heavy)) {! heavy = new HeavyFactory();! }! ! return heavy.get();! }! ! }

Slide 24

Slide 24 text

Conclusion

Slide 25

Slide 25 text

Java ʹΑΔؔ਺ܕϓϩάϥϛϯά Java 8 ϥϜμࣜͱ Stream ଞʹ΋ϥϜμࣜͷ࢖͑ΔςΫχοΫ͕ͨ͘͞ Μࡌ͍ͬͯ·͢ʢແݶϦετɺ࠶ؼݺͼग़͠ ࠷దԽͳͲʣɻ ࠓճ͸ Stream API ʹ͍ͭͯେ෯ʹলུͯ͠ ͍·͕͢ɺͦͪΒ΋͔ͬ͠Γ͓͍͑ͯ͞·͢ɻ ! ʮ࣌୅͸ Java!ʯͳͷͰങ͍!!