Upgrade to Pro — share decks privately, control downloads, hide ads and more …

パターンマッチングを学んで新しいJavaの世界へ!Java 18までの目玉機能をおさらいしよう / Java 18 pattern matching

パターンマッチングを学んで新しいJavaの世界へ!Java 18までの目玉機能をおさらいしよう / Java 18 pattern matching

Fb025419ed38f98df595eb2eafc859f4?s=128

ihcomega56

June 19, 2022
Tweet

More Decks by ihcomega56

Other Decks in Programming

Transcript

  1. ύλʔϯϚονϯάΛֶΜͰ ৽͍͠+BWBͷੈք΁ʂ +BWB·Ͱͷ໨ۄػೳΛ ͓͞Β͍͠Α͏ ++6($$$4QSJOH

  2. Θͨ͠ • Α͜ͳ !JIDPNFHB • %FWFMPQFS"EWPDBUF!+'SPH • ݩ͸ݱ৔ͷόοΫΤϯυΤϯδχΞ • ʰ͍ͪ͹Μ΍͍͞͠(JU(JU)VCͷڭՊॻʱ

    • ࠷ۙεΧΠμΠϏϯάΛͨ͠ 1
  3. ϦϦʔεαΠΫϧ͕มΘͬͨͷ͸ ೥݄ +BWB͔Β ΋͏೥͕ܦա͠Α͏ͱͯ͠Δʜ 2

  4. ΩϟονΞοϓͷ ਐḿͲ͏Ͱ͔͢ʁ 3

  5. Ξοϓσʔτͷྫ +BWB var nanikore = Map.of( 1, List.of("いぬ", "ねこ", "たぬき"),

    2, List.of("こあら", "ぱんだ")); ϩʔΧϧม਺ͷ ܕਪ࿦ 4
  6. Ξοϓσʔτͷྫ +BWB String memo = """ %s 以降 テキストブロックで 複数⾏の⽂字が

    書けるようになった """.formatted("Java 15"); ςΩετϒϩοΫ 5
  7. Ξοϓσʔτͷྫ +BWB if (sth instanceof String s) { System.out.println(s); }

    JOTUBODFPGʹΑΔ ύλʔϯ Ϛονϯά 6
  8. ෼͔Γ΍͍͢΋ͷɺ ΠϚΠνԿ͕خ͍͠ͷ͔ ௫ΈͮΒ͍΋ͷ ৭ʑ͋ΔΑͶ 7

  9. ࠓ೔ͷςʔϚ͸ ύλʔϯϚονϯά 8

  10. ͡Θ͡ΘਐΉػೳ֦ுʹΑΓ ݟ͑ͮΒ͘ͳ͍ͬͯΔ͔΋ ͠Εͳ͍ศར͞Λ Ұॹʹֶ΅͏ʂ 9

  11. ͜ͷηογϣϯͰ஌Ζ͏ • ύλʔϯϚονϯά • +BWB·ͰΛ࢖ͬͨύλʔϯϚονϯά • +BWBҎ߱ͰͷਐԽ • 1SPKFDU"NCFS΍ϦϦʔεαΠΫϧ 10

  12. ύλʔϯϚονϯάͱ͸ Ұൠ࿦ • ෼͔Γ΍͘͢ݴ͏ͱ৚݅൑ఆͷͻͱͭ • ஋Λύλʔϯͱর߹͠ɺҰக Ϛον ͢Δ͔֬ೝ͢Δ • Ұக͔ͨ͠Ͳ͏͔Ͱ৚݅Λ෼ذͨ͠Γɺ஋Λ෼ղͯ͠

    ࢖ͬͨΓ͢Δ͜ͱ΋Ͱ͖Δ 11
  13. ύλʔϯϚονϯάͱ͸ Ұൠ࿦ “Ն” “य़” “Ն” “ळ” “ౙ” 12

  14. ύλʔϯϚονϯάͱ͸ Ұൠ࿦ 🌻 🌹 🌸 🌷 🌸 🌸 🌸 🌸

    🌷 🌹 🌻 🌸 🌻 🌹 🌸 🌷 🌻 🌹 ❓ ❓ 💐 💐 💐 💐 13
  15. ύλʔϯϚονϯάͱ͸ 🌻 🌹 🌸 🌷 🌻 🌹 ❓ 🌷 Bʹ

    🌹 র߹ ෼ղ Cʹ 🌸 14
  16. +BWBͰύλʔϯϚονϯά • TXJUDIࣜ • JOTUBODFPGΛ࢖ͬͨύλʔϯϚονϯά • TXJUDIΛ࢖ͬͨύλʔϯϚονϯά • Ϩίʔυ 3FDPSE

    • γʔϧΫϥε 4FBMFEDMBTT +BWB͔Β গͣͭ͠ ಋೖ͞Ε͍ͯΔΑ 15
  17. ͲͷόʔδϣϯͰԿ͕ೖ͔ͬͨ͸ ͍ͬͨΜ๨Εͯɺ +BWB ϓϨϏϡʔؚΉ  ͰͰ͖Δ͜ͱ Λ ·ͣ͸஌Ζ͏ 16

  18. ϓϨϏϡʔػೳͱ͸ • ਖ਼ࣜϦϦʔεલͷػೳ • ࣮ࡍʹ࢖ͬͯͷϑΟʔυόοΫΛಘΔͨΊެ։͞ΕΔ • KBWBD΍KBWBίϚϯυʹ FOBCMFQSFWJFXϑϥάΛ ෇͚࣮ͯߦ͢Δͱ༗ޮʹͳΔ •

    KBWBDSFMFBTFEFOBCMFQSFWJFX)PHFKBWB • KBWBFOBCMFQSFWJFX)PHF • KTIFMM΍KBWBEPDίϚϯυͰ΋࢖͑Δ • *%&Ͱ΋αϙʔτ͕͋Δ 17
  19. γϯϓϧͳύλʔϯϚονϯά String season = “夏”; String result = switch (season)

    { case “春” -> “Spring”; case “夏” -> “Summer”; case “秋” -> “Fall”; case “冬” -> “Winter”; default -> "Nothing"; } 18
  20. TXJUDIࣜ • TXJUDIΛʮࣜʯͱͯ͠࢖͑Δʢ஋Λฦ͢ʣ • ͜Ε΋ύλʔϯϚονϯάͷͻͱͭʢఆ਺ύλʔϯʣ 19

  21. ΋͏গ͠ෳࡶͳྫͰ ύλʔϯϚον ϏϑΥʔΞϑλʔΛ ݟ͍ͯ͜͏ 20

  22. ߟ͑Δͷʹ࢖͏αϯϓϧ ϝϞா • ςΩετϝϞ • 50%0Ϧετ • ը૾͖ͭςΩετϝϞ • શͯ*%ͱλΠτϧΛ࣋ͭ

    • ϝϞͷߏ଄͕֤ʑҟͳΔ 21
  23. γφϦΦ ϞσϧΛ༻ҙ͢Δ ௚઀తʹ͸ ύλʔϯϚονϯάͷ ࿩Ͱ͸ͳ͍͚Ͳ ޙʑ࢖͏ͷͰ঺հ͠·͢ 22

  24. ϞσϧΛ༻ҙ͢Δ • େྔͷΫϥεΛ࡞੒͢Δ • ͦͷ෼ϘΠϥʔϓϨʔτ΋ॻ͘ 23

  25. ϞσϧΛ༻ҙ͢Δ چ public class Text implements Memo { private Id

    id; private Title title; private Body body; public Text(Id id, Title title, Body body) { this.id = id; this.title = title; this.body = body; } // setter/getter // toString() // equals() // hashCode() } 24
  26. ՝୊ • ͍ͨ΁Μ 25

  27. ϞσϧΛ༻ҙ͢Δ ৽ record Text(Id id, Title title, Body body) implements

    Memo {} 26
  28. ϨίʔυΫϥε record Text(Id id, Title title, Body body) implements Memo

    {} • SFDPSEΩʔϫʔυ෇͖ͰΫϥεΛఆٛ͢Δ • (Id id, Title title, Body body) ෦෼ʮ Ϩίʔυ ϔομʔʯʹ ʮ Ϩίʔυ ίϯϙʔωϯτʯΛఆٛͰ͖Δ 27
  29. ϨίʔυΫϥε Լه͕ࣗಈͰੜ੒͞ΕΔ • ϔομʔͱಉ͡ϑΟʔϧυΛ࣋ͬͨίϯετϥΫλ • ֤ίϯϙʔωϯτʹରͯ͠ͷ • QSJWBUFGJOBMͳϑΟʔϧυ ίϯϙʔωϯτͱಉ໊ •

    QVCMJDͳΞΫηαʔϝιου ίϯϙʔωϯτͱಉ໊ • FRVBMT ϝιου IBTI$PEF ϝιου ಉ͡ܕͰ֤ίϯϙʔωϯτ͕ಉ͡஋Λ࣋ͬͨϨίʔυ͔Ͳ͏͔ • UP4USJOH ϝιουίϯϙʔωϯτͷ໊લͱ஋Λฦ͢ 28
  30. ϨίʔυΫϥε • ϨίʔυΫϥεɺίϯϙʔωϯτ͔Βੜ੒͞ΕͨϑΟʔϧυ͸ ҉໧తʹGJOBM ΠϯελϯεΛΠϛϡʔλϒϧʹอͭࢥ૝ • ଞͷΫϥεΛܧঝͰ͖ͳ͍ KBWBMBOH3FDPSEΛܧঝ͍ͯ͠Δ ͨΊ •

    ΠϯλʔϑΣʔεͷ࣮૷͸Ͱ͖Δ • ଞͷΫϥε͔Βͷܧঝ΋Ͱ͖ͳ͍ GJOBMͳͷͰ • Ϋϥεͱಉ༷ϝιου͕એݴͰ͖Δ • ϔομʔҎ֎ʹΠϯελϯεϑΟʔϧυ͸એݴͰ͖ͳ͍ 29
  31. ϨίʔυΫϥε public interface Memo { … record Text(Id id, Title

    title, Body body) implements Memo {} record TodoList(Id id, Title title, List<Task> tasks) implements Memo {} record Image … } • Ϋϥε΍ΠϯλʔϑΣʔεͷதʹఆٛͰ͖Δ • ೖΕࢠʹ͢Δ͜ͱͳ͘ಉϑΝΠϧʹఆٛ΋Ͱ͖Δ • ΋ͪΖΜผϑΝΠϧͰͷఆٛ΋Ͱ͖Δ ͜͏͢Ε͹ϑΝΠϧʹఆٛͰ͖Δ͕ QVCMJDͳϨίʔυʹ͍ͨ͠৔߹ ೖΕࢠʹ͢Δ͔͠ͳ͍ɻ ݟ׳Εͳ͍ίʔυʹͳΔ΋ͷͷศར 30
  32. γφϦΦ ϏδωεϩδοΫ࣮૷ฤ ϝϞͷछྨ͝ͱʹॲཧΛৼΓ෼͚Δ 31

  33. String doSomethingForEach(Memo memo) { if (memo == null) { return

    "nullが来た"; } else if (memo instanceof Text) { Text text = (Text) memo; return doSomethingForText(text); } else if (memo instanceof TodoList) { TodoList todo = (TodoList) memo; return doSomethingForTodoList(todo); } else if (memo instanceof Image) { Image image = (Image) memo; return doSomethingForImage(image); } else { return "おかしな値が来た"; } } ϝϞͷछྨ͝ͱʹ ॲཧΛৼΓ෼͚Δ چ 32
  34. ՝୊ • JGFMTF஍ࠈʹؕΔ • ܕʹΑΔ൑ఆΛߦ͏ࡍɺ൑ఆͱ࢖༻͕ผͷεςοϓʹ෼͔ΕΔ • ͭ·Γɺίʔυྔ͕΍ͨΒͱଟ͘ͳͬͯಡΈͮΒ͍ 33

  35. String doSomethingForEach(Memo memo) { return switch (memo) { case null

    -> “nullが来た”; case Text t -> doSomethingForText(t); case TodoList td -> doSomethingForTodoList(td); case Image i -> doSomethingForImage(i); default -> "おかしな値が来た"; }; } ϝϞͷछྨ͝ͱʹ ॲཧΛৼΓ෼͚Δ ৽ 34 ໼ҹ͕ἧ͏Α͏ͳ ϑΥʔϚοτʹ͢Δͱ ಡΈ΍͍͢
  36. ܕͰύλʔϯϚονϯά • ܕͰύλʔϯϚονϯάͰ͖Δ ܕʗλΠϓύλʔϯ • ܕʹϚονͨ͠Β஋͕ม਺ʹऔΓग़͞ΕΔ • ύλʔϯม਺ͱݴ͍ɺείʔϓ͸Ϛονͨ͠έʔεͷதͷΈ • Ϩίʔυͱͯ͠ఆٛ͞ΕͨܕͰ΋ύλʔϯϚονϯάͰ͖Δ

    35
  37. case null, Text t -> “null͔ςΩετϝϞ”; case null, default ->

    “null͔͓͔͠ͳ஋”; • ࠓͷͱ͜ΖҟͳΔܕΛ·ͱΊͯॻ͘͜ͱ͸Ͱ͖ͳ͍͕ɺOVMMͱ ଞͷέʔε͸·ͱΊΒΕΔ • OVMMͷ৔߹ύλʔϯม਺Λ࢖͏ͱ౰વ/VMM1PJOUFS&YDFQUJPO ϝϞͷछྨ͝ͱʹ ॲཧΛৼΓ෼͚Δ ৽ 36
  38. γφϦΦ ϏδωεϩδοΫ࣮૷ฤ ͞Βʹࡉ͔͘ॲཧΛৼΓ෼͚Δ 37

  39. String doSomethingForEach(Memo memo) { if (memo == null) { return

    “nullが来た”; } else if (memo instanceof Text) { Text text = (Text) memo; return doSomethingForText(text); } else if (memo instanceof TodoList) { TodoList todo = (TodoList) memo; if (0 < todo.tasks().size()) { return doSomethingForTodoList(todo); } else { return "ToDoが空っぽ"; } } else if (memo instanceof Image) { Image image = (Image) memo; return doSomethingForImage(image); } else { return "おかしな値が来た"; } } ৚݅Λ௥Ճ͢Δ چ 38
  40. … } else if (memo instanceof TodoList) { TodoList todo

    = (TodoList) memo; if (0 < todo.tasks().size()) { return doSomethingForTodoList(todo); } else { return "ToDoが空っぽ"; } } else if… ৚݅Λ௥Ճ͢Δ چɾ֦େ 39
  41. ՝୊ • ෳࡶ͕͞ߴ·ΓՄಡੑ͕ͲΜͲΜԼ͕Δ 40

  42. return switch (memo) { case null -> "nullが来た"; case Text

    t -> doSomethingForText(t); case TodoList td && 0 < td.tasks().size() -> doSomethingForTodoList(td); case TodoList td -> "ToDoが空っぽ"; case Image i -> doSomethingForImage(i); default -> "おかしな値が来た"; }; ৚݅Λ௥Ճ͢Δ ৽ 41
  43. ΨʔυύλʔϯʗύλʔϯΨʔυ case TodoList td && 0 < td.tasks().size() -> doSomethingForTodoList(td);

    case TodoList td -> "ToDoが空っぽ"; • ύλʔϯϚονϯάʹ৚݅Λ௥ՃͰ͖Δ • ৚݅ʹ߹க͠ͳ͍৔߹ͷॲཧΛॻ͖๨Εͳ͍Α͏ʹ͠Α͏ 42
  44. γφϦΦ ࢓༷มߋฤ ϝϞͷछྨΛ૿΍͢ 43

  45. ϝϞͷछྨΛ૿΍͢ public interface Memo { … record Text(Id id, Title

    title, Body body ) implements Memo {} record TodoList(Id id, Title title, List<Task> tasks) implements Memo {} record Image(Id id, Title title, ImageUrl url, Body body ) implements Memo {} record Video(Id id, Title title, VideoUrl url ) implements Memo {} } 44
  46. return switch (memo) { case null -> "nullが来た"; case Text

    t -> doSomethingForText(t); case TodoList td && 0 < td.tasks().size() -> doSomethingForTodoList(td); case TodoList td -> "ToDoが空っぽ"; case Image i -> doSomethingForImage(i); case Video v -> doSomethingForVideo(v); default -> "おかしな値が来た"; }; ϝϞͷछྨΛ૿΍͢ 45
  47. ՝୊ • ݺͼग़͠Օॴͷௐ͕ࠪେมɾݟམͱ͠ͷ΋ͱ 46

  48. ϝϞͷछྨΛ૿΍͢ sealed public interface Memo { … record Text(Id id,

    Title title, Body body ) implements Memo {} record TodoList(Id id, Title title, List<Task> tasks) implements Memo {} record Image(Id id, Title title, ImageUrl url, Body body) implements Memo {} record Video(Id id, Title title, Video Url url) implements Memo {} } 47
  49. γʔϧ υ Ϋϥε • TFBMFEΩʔϫʔυΛ͚ͭͯఆٛͨ͠Ϋϥε΍ΠϯλʔϑΣʔε • ܧঝɾ࣮૷ՄೳͳΫϥεΛԼهͷΈʹݶఆ͢Δ Ϩίʔυ΋Մ • QFSNJUT۟Λ͚ͭͯڐՄͨ͠Ϋϥε

    sealed public interface Memo permits Text, TodoList, Image, Video • ಉ͡ϑΝΠϧʹఆٛͨ͠Ϋϥε • ܕʹΑΔύλʔϯϚονϯάͰ͢΂ͯͷܕΛ໢ཏ͍ͯ͠Δ͜ͱ Λ୲อͰ͖Δ ໢ཏ͍ͯ͠ͳ͍৔߹͸ίϯύΠϧΤϥʔ • ύλʔϯϚονϯάʹ͓͚ΔEFGBVMU͕ඞਢͰͳ͘ͳΔ 48
  50. return switch (memo) { case null -> "nullが来た"; case Text

    t -> doSomethingForText(t); case TodoList td && 0 < td.tasks().size() -> doSomethingForTodoList(td); case TodoList td -> "ToDoが空っぽ"; case Image i -> doSomethingForImage(i) ; case Video v -> doSomethingForVideo(v); }; ϝϞͷछྨΛ૿΍͢ 49
  51. ͜͜·Ͱͷ͓͞Β͍ • ύλʔϯϚονϯάΛ׆༻ͯ͠ϘΠϥʔϓϨʔτ͕ݮΒͤΔ • ݱঢ় +BWBͷύλʔϯϚονϯά͸TXJUDIΛ׆༻͢Δ • ܕύλʔϯΛ࢖͏ͱ͖͸γʔϧΫϥεͰϛε΋ݮΒͤΔ • ܕΛ׆༻͢Δ্ͰϨίʔυ͸͔ܽͤͳ͍

    50
  52. Ϩίʔυ͚ͩ ύλʔϯϚονϯάͱ བྷΊΔʹ͸ͪΐͬͱऑ͍ʜʁ 51 ͋ͱɺࠓ೔ͷྫͷΑ͏ʹ ෼ذޙʹ݁ہಉ͡Α͏ͳ ॲཧΛ͍ͤͨ͞৔߹ɺ ܧঝͰྑ͍ͷͰ͸ʁͱ͔

  53. +BWBʹظ଴ if (memo instanceof Text(Id id, Title title, Body body))

    { show(body); } --- OR --- if (memo instanceof Text(var id, var title, var body)) { show(body); } • Ϩίʔυύλʔϯ͕ಋೖ͞ΕΔ༧ఆ ϓϨϏϡʔ • ϨίʔυΛ༻͍ͨύλʔϯϚονϯάʹ͓͍ͯ෼ղ͕༰қʹͳΔ 52
  54. ΋ͬͱকདྷ ˞ΠϝʔδͰ͢ String doSomethingForEach(Memo memo) { return switch (memo) {

    case null -> "nullが来た"; case Text(Id id, Title title, Body body) -> doSomethingForText(body); case TodoList(Id id Title title, List<Task> tasks) && 0 < tasks().size() -> doSomethingForTodoList(tasks); case TodoList _ -> "ToDoが空っぽ"; case Image(Id id, Title title, ImageUrl url, Body body) -> doSomethingForImage(url, body); }; } 53
  55. Ϩίʔυύλʔϯɺ෼ղ 54 • ʮͲͷܕ͔ʯͷΈͳΒͣʮͲΜͳߏ଄͔ʯΛ;·͑ͯύλʔϯ ϚονϯάͰ͖Δ • ܧঝʹΑΔϙϦϞʔϑΟζϜ͚ͩͰදݱͮ͠Β͍ෳࡶͳέʔε ʢΦʔόʔϩʔυͨ͘͠ͳͬͨ࣌ͱ͔ʣͰ͸ಛʹ׆༻Ͱ͖Δ

  56. +BWBͰͷখ͞ͳมߋ case TodoList td when 0 < td.tasks().size() -> doSomethingForTodoList(td);

    • Ψʔυύλʔϯͷࢦఆ͕ Ͱ͸ͳ͘ XIFOʹมΘΔ • ෼͔Γ΍͢͞ͷͨΊΒ͍͠ 55
  57. +BWBύλʔϯϚονϯάมભ         ϓϨϏϡʔ

    ਖ਼ࣜϦϦʔε TXJUDIࣜ JOTUBODFPG ύλʔϯϚον Ϩίʔυ γʔϧυ TXJUDI ύλʔϯϚον Ϩίʔυ ύλʔϯ 56
  58. 1SPKFDU"NCFS • 0QFO+%,ͷ։ൃ͸ϓϩδΣΫτ୯ҐͰਐΉ • IUUQTPQFOKELKBWBOFUQSPKFDUT • ΰʔϧΛ໨ࢦͯ͠গͣͭ͠ػೳ௥Ճ͞ΕΔͷͰɺϓϩδΣΫτ ͱ͍͏୯Ґʹ஫໨͢Δͱ෼͔Γ΍͍͢ • ͜͜·Ͱ঺հͨ͠ύλʔϯϚονϯάɺςΩετϒϩοΫɺ

    WBS͸શ෦ʮ1SPKFDU"NCFSʯͷ੒Ռ • IUUQTPQFOKELKBWBOFUQSPKFDUTBNCFS • 1SPKFDU"NCFS͸ݴޠʹؔ͢Δػೳվળू 57
  59. ࠷৽ͷ৘ใΛಘΔʹ͸ • +&1 +%,&OIBODFNFOU1SPQPTBM ͰϩʔυϚοϓΛ֬ೝͰ͖Δ • ྫTXJUDIࣜ͸+&1  +&1ͦͷ΋ͷͷઆ໌͸+&1 

    • 0QFO+%,ͷެࣜϖʔδΛݟΔͱ෼͔Γ΍͍͢ • IUUQTPQFOKELKBWBOFUQSPKFDUTKEL • ໨తɾ࢓༷΍࢖͍ํɾલճͱͷࠩ෼͕؆ܿʹॻ͔Ε͍ͯΔ • 'VUVSFXPSLΛಡΉͱ͞ΒͳΔల๬͕෼͔Δ • +&1ಉ࢜ͷؔΘΓ͕௫ΊΔ 58
  60. ࠷ޙʹҰൠ+BWBϢʔβʔ໨ઢͰʜ • ௥͏ͷ͸େม • ͲΜͲΜ৽͍͠όʔδϣϯ͕΍ͬͯ͘Δ • ϓϨϏϡʔػೳ΋͋ͬͯࠓԿ͕ग़དྷΔͷ͔෼͔Βͳ͍ • ԕ͘ʹ͋Δ໨త΍ҙຯΛ೺Ѳ͢Δͱ͔͑ͬͯ෼͔Γ΍͍͢ •

    +&1΍ϓϩδΣΫτ͸ϚχΞοΫͳ஌ࣝͩͱࢥ͍ͬͯΔํ΋ɺ ஌Δ͜ͱͰָʹͳΕΔ͔΋ʜʁ ʜͦ͏͸͍ͬͯ΋େมͳͷͰίϛϡχςΟ΋׆༻͠Α͏ʂ🌟 59
  61. 5IBOLZPV 60