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

あたらしい もじれつの かきかた

Aya Ebata
February 02, 2024

あたらしい もじれつの かきかた

2024/02/03 Java女子部
Java 8から21まで いまどきJavaの文法再入門の会!
https://javajo.doorkeeper.jp/events/168055

Aya Ebata

February 02, 2024
Tweet

More Decks by Aya Ebata

Other Decks in Technology

Transcript

  1. 自己紹介 - 名前: えばた あや - Twitter: @aya_122 - 好き:

    ラーメン二郎 / イクラ / ポケモン - お仕事: フリーランス - Go / React / Python / Vue / Android - 久々にJVM言語のお仕事してるんだ!わーい!Androidだけど!w
  2. String Templatesとは - Javaの既存の文字列リテラルとテキストブロックを補完する 文字列リテラル String str = "hoge";       ↑ここ!

    テキストブロック String json = """ { "name": "web", "version": "1.0.0", } """;  ↑"""で囲まれてる部分のこと!
  3. String Templatesの登場人物 STR."My name is \{name}" - テンプレート式: STR."My name

    is \{name}" - テンプレートプロセッサ: STR - テンプレート: "My name is \{name} " - 埋め込み式: \{name}
  4. 今までの書き方 - 文字列を+演算子で連結する String s = x + " plus

    " + y + " equals " + (x + y); -> 読みにくいコードになる…
  5. 今までの書き方 - StringBuilderを使う String s = new StringBuilder() .append(x) .append("

    plus ") .append(y) .append(" equals ") .append(x + y) .toString();      -> 冗長…
  6. 今までの書き方 - String::format や String::formatted を使う String s = String.format("%2$d

    plus %1$d equals %3$d", x, y, x + y); String t = "%2$d plus %1$d equals %3$d".formatted(x, y, x + y); -> 文字列とパラメータが分離してしまう…
  7. 今までの書き方 - java.text.MessageFormatを使う MessageFormat mf =   new MessageFormat("{0} plus {1}

    equals {2}"); String s = mf.format(x, y, x + y); -> 多くの式を必要とし、見慣れない構文を使用する… という欠点があったらしい><
  8. テンプレート式に計算式を埋め込む int x = 10, y = 20; String s

    = STR."\{x} + \{y} = \{x + y}"; System.out.println(s); // 10 + 20 = 30 - 数値もそのまま使える! - \{...}の中で計算もできる!
  9. 埋め込み式からメソッドを呼び出す String getCommunityName() { return "Java女子部"; } void main(){ String

    s = STR."今日は\{getCommunityName()}の勉強会"; System.out.println(s); // 今日はJava女子部の勉強会 }
  10. 埋め込み式からフィールドにアクセスする record Person(String name, String like) { } void main(){

    Person person = new Person("あや", "ポケモン"); String t = STR."\{person.name}です。\{person.like}が好きです。"; System.out.println(t); // あやです。ポケモンが好きです。 }
  11. ダブルクォーテーションを埋め込み式内で使用する String filePath = "tmp.dat"; File file = new File(filePath);

    // String old = // "The file " + filePath + " " + (file.exists() ? "does" : "does not") + // " exist"; String msg = STR."The file \{filePath} \{file.exists() ? "does" : "does not"} exist"; System.out.println(msg); // The file tmp.dat does not exist 三項演算子で文字列を表現しやすくなる!
  12. テンプレート式に複数行の処理を埋め込む String time = STR."The time is \{ DateTimeFormatter .ofPattern("HH:mm:ss")

    .format(LocalTime.now()) } right now"; System.out.println(time); // The time is 23:21:42 right now(実行した時間)
  13. 埋め込み式内でテンプレート式を入れ子にする String[] fruit = {"apples", "oranges", "peaches"}; String s =

    STR."\{fruit[0]}, \{ STR."\{fruit[1]}, \{fruit[2]}" }"; System.out.println(s); // apples, oranges, peaches
  14. 例: HTMLで使用 String title = "My Web Page"; String text

    = "Hello, world"; String html = STR.""" <html> <head> <title>\{title}</title> </head> <body> <p>\{text}</p> </body> </html> """; System.out.println(html);  ↓ <html> <head> <title>My Web Page</title> </head> <body> <p>Hello, world</p> </body> </html>
  15. 例: JSONで使用 String name = "Joan Smith"; String phone =

    "555-123-4567"; String address = "Anytown"; String json = STR.""" { "name": "\{name}", "phone": "\{phone}", "address": "\{address}" } """; System.out.println(json);  ↓ { "name": "Joan Smith", "phone": "555-123-4567", "address": "Anytown" }
  16. FMTの例 record Restaurant(String name, double star) {} Restaurant[] restaurants =

    new Restaurant[]{ new Restaurant("RamenJiro", 4.5), new Restaurant("Sushiro", 3.4), new Restaurant("Sukiya", 2.2), };
  17. FMTの例 String table = FMT.""" Restaurant Star %-12s\{restaurants[0].name} %4.2f\{restaurants[0].star} %-12s\{restaurants[1].name}

    %4.2f\{restaurants[1].star} %-12s\{restaurants[2].name} %4.2f\{restaurants[2].star} \{" ".repeat(5)} Average %4.2f\{ (restaurants[0].star + restaurants[1].star + restaurants[2].star) / 3 } """;
  18. RAWの例 String name = "Joan"; String info = STR."My name

    is \{name}";   || String name = "Joan"; StringTemplate st = RAW."My name is \{name}"; String info = STR.process(st);
  19. StringTemplateクラス fragmentsとvaluesを持っている! int x = 10, y = 20; StringTemplate

    st = RAW."\{x} plus \{y} equals \{x + y}"; String s = st.toString(); System.out.println(s); // StringTemplate{ // fragments = [ "", " plus ", " equals ", "" ], // values = [10, 20, 30] // }
  20. カスタマイズの例 var INTER = StringTemplate.Processor.of((StringTemplate st) -> { String placeHolder

    = "•"; String stencil = String.join(placeHolder, st.fragments()); for (Object value : st.values()) { String v = String.valueOf(value); stencil = stencil.replaceFirst(placeHolder, v); } return stencil; });
  21. カスタマイズの例 String placeHolder = "•"; String stencil = String.join(placeHolder, st.fragments());

    st.fragments() -> ["", " plus ", " equals ", ""] "\{x} plus \{y} equals \{x + y}"の文字列だけを配列で返す String.join(placeHolder, st.fragments()) -> "• plus • equals •" placeHolderを区切り文字にして文字列として連結する
  22. カスタマイズの例 for (Object value : st.values()) { String v =

    String.valueOf(value); stencil = stencil.replaceFirst(placeHolder, v); } st.values() -> [10, 20, 30] "\{x} plus \{y} equals \{x + y}"の埋め込み式の結果を配列で返す stencil.replaceFirst(placeHolder, v) -> "10 plus 20 equals 30" placeHolderを前から1つずつst.values()の値で置き換えていく
  23. カスタマイズの例 int x = 10, y = 20; String s

    = INTER."\{x} plus \{y} equals \{x + y}"; System.out.println(s); // 10 plus 20 equals 30 -> STRのような実装になる!
  24. StringTemplate.Processorのインターフェースの実装例 戻り値がJSONObjectでJSONExceptionのExceptionを吐く StringTemplate.Processor<JSONObject, JSONException> JSON_VALIDATE = (StringTemplate st) -> {

    (省略) return new JSONObject(jsonSource); }; 上記の実装の途中で以下のExceptionを投げることができるよ throw new JSONException("エラーだよ");
  25. ロケールの変更 Date today = new Date(); FormatProcessor JA = FormatProcessor.create(Locale.JAPAN);

    String jaStr = JA."今月は%tB\{today}"; System.out.println(jaStr); // 今月は2月 FormatProcessor US = FormatProcessor.create(Locale.US); String usStr = US."This month is %tB\{today}"; System.out.println(usStr); // This month is February