- 投稿日:2019-10-23T23:15:15+09:00
どうしても「new T()」したい!(しかも検査例外なしで)
結論
T型のインスタンスを生成する関数型インターフェースのインスタンスを、引数で受け取る。
// newT()が必要なメソッド <T> T doSomething(Supplier<T> supplier) { T instance = supplier.get(); return instance; } // doSomethingを呼び出すメソッド void caller() { Test instance = this.doSomething(() -> new Test()); }解説
そもそも
new T()がアンチパターンなのはわかっていても、new T()したいときもある。
そのときの解決法としてよく提示されるのが以下のパターン。ClassインスタンスをもらってnewInstance()する
<T> T doSomething(Class<T> clazz) throws InstantiationException, IllegalAccessException { T instance = clazz.newIntance(); return instance; } void caller() { Test instance = this.doSomething(Test.class); }このコードの問題点は検査例外をスローすること。
検査例外をスローする
上述のコードの通り、
InstantiationExceptionとIllegalAccessExceptionをスローする。
Class.newInstance()側としては妥当な設計だとは思うが、使う側としてはコンストラクタが例外をスローしないことを確信できる場合もあるわけで…。
そうするとわざわざ上記例外をtry-catchしたりthrowsしたりするのは面倒くさい。
さらに検査例外なので、streamと相性が悪く1、内部でtry-catchが必要になる<T extends SuperTest> List<T> doSomething(Class<T> clazz, List<String> valueList) throws InstantiationException, IllegalAccessException { return valueList.stream() .map(value -> { // せっかくstreamでスマートに書きたいのにtry-catch… try { T obj = clazz.newInstance(); obj.setValue(value); } catch (Exception e) { throw new RuntimeException(e); } }) .collect(Collectors.toList()); }その点、関数型インターフェースは余計な検査例外が発生しないので比較的綺麗にかける(コンストラクタに
throwsがある場合は別)。余談
コンストラクタが引数をとる場合は
Function<T, R>のインスタンスを使う。
2つならBiFunction<T, U, R>。
3つ以上の場合は、引数のためのクラスを作るなり、java.util.Mapを使うなりする。引数が1つ// newT()が必要なメソッド <T> T doSomething(Function<String, T> func) { T instance = func.apply("コンストラクタの引数"); return instance; } // doSomethingを呼び出すメソッド void caller() { Test instance = this.doSomething((str) -> new Test(str)); }引数が2つ// newT()が必要なメソッド <T> T doSomething(BiFunction<String, Integer, T> func) { T instance = func.apply("コンストラクタの引数", 1); return instance; } // doSomethingを呼び出すメソッド void caller() { Test instance = this.doSomething((str, number) -> new Test(str, number)); }
正確には関数型インターフェースと相性が悪い。 ↩
- 投稿日:2019-10-23T20:52:13+09:00
EclipseにLombokを設定する方法
- 環境
- Windows10 Pro 64bit
- java version 1.8.0_231
- Eclipse Oxygen.3a Release (4.7.3a)
- 設定対象 : Lombok Version : 1.16.18
事前準備
- Eclipseを開いている場合は閉じる
ダウンロードする
- projectlombok.orgからjar(lombok-1.16.18.jar)ファイルをダウンロードする
Eclipseに設定する
$ java -jar /path/to/lombok-1.16.18.jarでjarを実行してダイアログを開く
- jarファイルをダブルクリックしても開く
- 表示されたEclipseにチェックを入れて[Install/Update]ボタンでインストールする
- eclipse.iniに
-javaagent:lombok.jarが追記される- [Quit Installer]ボタンでダイアログを閉じる
- 投稿日:2019-10-23T20:21:55+09:00
【Kotlin】「is~」で始まるメソッドでBoolean?を返す場合AssertTrue / AssertFalseでバリデーションできない【BeanValidation】
記事内容はタイトル通りです。
こうなる原理は以下の記事をご参照ください。
概要
メソッドに
AssertTrueを付けた場合、バリデーションできる/できないは以下のようになります。// バリデーションできる @AssertTrue fun getHoge(): Boolean? = false // バリデーションできない @AssertTrue fun isHoge(): Boolean? = false // バリデーションできる @AssertTrue fun isFuga(): Boolean = false原因
以下は上記コードのデコンパイル結果です。
KotlinはBoolean?型をjava.lang.Booleanにコンパイルします。
そして、冒頭に貼り付けた記事の通り、java.lang.Booleanはオブジェクトなので、BeanValidationはis~から始まるメソッドを無視してしまうため、バリデーションは機能しません。@AssertTrue @Nullable public final Boolean getHoge() { return false; } @AssertTrue @Nullable public final Boolean isHoge() { return false; } @AssertTrue public final boolean isFuga() { return false; }
- 投稿日:2019-10-23T19:25:49+09:00
Spring Boot 2.2.0でLazy Initializationを試してみた
Spring Boot v2.2.0
Spring Boot v2.2.0がリリースされ、GAとなりました。
なので、その機能の一つであるLazyInitializationについて検証してみます。
Spring Boot 2.2.0
Release v2.2.0.RELEASE · spring-projects/spring-boot · GitHub
Spring Boot 2.2 Release Notes · spring-projects/spring-boot Wiki · GitHub
Spring Boot Reference Documentation環境
- Windows10
- OracleJDK 13(build 13)
- Spring Boot 2.2.0 RELEAS
Projectの作成
ひながたとなるProjectは、Spring Initializrから作成します。
Gradle
Spring Initializrで作成したGradleプロジェクトでは、Gradle 5.6.2が適用されることを確認しました。
> gradlew -version ------------------------------------------------------------ Gradle 5.6.2 ------------------------------------------------------------ Build time: 2019-09-05 16:13:54 UTC Revision: 55a5e53d855db8fc7b0e494412fc624051a8e781 Kotlin: 1.3.41 Groovy: 2.5.4 Ant: Apache Ant(TM) version 1.9.14 compiled on March 12 2019 JVM: 13-ea (Oracle Corporation 13-ea+33) OS: Windows 10 10.0 amd64Lazy Initialization
ApplicationContextで管理するBeanの生成を、アプリケーションの起動時(≒ApplicationContextの初期化時)ではなくて、対象のBeanの呼び出しがされる際に行うのが、Lazy Initializationです。
この機構は以前のバージョンからもありますが、v2.2.0からはproperty
spring.main.lazy-initializationにtrueを適用することで、一律LazyInitializationが適用されます。
- application.yml
spring: main: lazy-initialization: true
- Bean class
package jp.co.musako.domain.model; public class LazyInitializationDemoBean { private String message; public LazyInitializationDemoBean(String message) { this.message = message; System.out.println("call constructor " + this.message); } public void writer(String message){ System.out.println(this.message + " is " + message); } }
- config class
package jp.co.musako.config; import jp.co.musako.domain.model.LazyInitializationDemoBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class Config { @Bean("lazyInitializationDemoBean1") public LazyInitializationDemoBean lazyInitializationDemoBean1(){ return new LazyInitializationDemoBean("create lazyInitializationDemoBean1"); } @Bean("lazyInitializationDemoBean2") public LazyInitializationDemoBean lazyInitializationDemoBean2(){ return new LazyInitializationDemoBean("create lazyInitializationDemoBean2"); } }
- main class
package jp.co.musako; import jp.co.musako.domain.model.LazyInitializationDemoBean; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ApplicationContext; @SpringBootApplication public class Application { public static void main(String[] args) { ApplicationContext ctx = SpringApplication.run(Application.class, args); System.out.println("Initialize Application Context"); LazyInitializationDemoBean bean1 = ctx.getBean("lazyInitializationDemoBean1", LazyInitializationDemoBean.class); bean1.writer("first bean"); LazyInitializationDemoBean bean2 = ctx.getBean("lazyInitializationDemoBean2", LazyInitializationDemoBean.class); bean2.writer("second bean"); } }実行結果
>gradlew bootRun > Task :bootRun 2019-10-23 18:16:37.620 INFO 12708 --- [ main] jp.co.musako.Application : Started Application in 4.295 seconds (JVM running for 4.933) Initialize Application Context call constructor lazyInitializationDemoBean1 lazyInitializationDemoBean1 is first bean call constructor lazyInitializationDemoBean2 lazyInitializationDemoBean2 is second beanここで、以下の順序で処理がされていることがわかります。
- アプリケーション起動
- 起動後に「Initialize Application Context」を出力
- Beanの生成
- Beanのコンストラクタ内で「call constructor lazyInitializationDemoBean1」を出力
- 生成したBeanのwriterメソッドが呼び出される
- writerメソッドで「lazyInitializationDemoBean1 is first bean」を出力
Lazy Initializationの適用除外
spring.main.lazy-initialization=trueを設定してLazyInitializationをプロジェクトに適用しつつ、特定のBeanをLazyInitializationの対象外とするには以下の方法があります。
@org.springframework.context.annotation.Lazy(false)をBeanに設定するorg.springframework.boot.LazyInitializationExcludeFilterに対象外とするBeanを登録する
- config class
package jp.co.musako.config; import jp.co.musako.domain.model.ExcludeLazyInitializationDemoBean; import jp.co.musako.domain.model.LazyInitializationDemoBean; import org.springframework.boot.LazyInitializationExcludeFilter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; @Configuration public class Config { @Bean static LazyInitializationExcludeFilter integrationLazyInitExcludeFilter() { return LazyInitializationExcludeFilter.forBeanTypes(ExcludeLazyInitializationDemoBean.class); } // Lazy Initialization適用対象 @Bean("lazyInitializationDemoBean1") public LazyInitializationDemoBean lazyInitializationDemoBean1(){ return new LazyInitializationDemoBean("lazyInitializationDemoBean1"); } // Lazy Initialization適用対象外 @Bean("lazyInitializationDemoBean2") @Lazy(false) public LazyInitializationDemoBean lazyInitializationDemoBean2(){ return new LazyInitializationDemoBean("lazyInitializationDemoBean2"); } // Lazy Initialization適用対象外 @Bean public ExcludeLazyInitializationDemoBean ExcludeLazyInitializationDemoBean(){ return new ExcludeLazyInitializationDemoBean("excludeLazyInitializationDemoBean"); } }
- main class
package jp.co.musako; import jp.co.musako.domain.model.ExcludeLazyInitializationDemoBean; import jp.co.musako.domain.model.LazyInitializationDemoBean; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ApplicationContext; @SpringBootApplication public class Application { public static void main(String[] args) { ApplicationContext ctx = SpringApplication.run(Application.class, args); System.out.println("Initialize Application Context"); LazyInitializationDemoBean bean1 = ctx.getBean("lazyInitializationDemoBean1", LazyInitializationDemoBean.class); bean1.writer("first bean"); LazyInitializationDemoBean bean2 = ctx.getBean("lazyInitializationDemoBean2", LazyInitializationDemoBean.class); bean2.writer("second bean"); ExcludeLazyInitializationDemoBean ExcludeLazyInitializationBean = ctx.getBean("ExcludeLazyInitializationDemoBean", ExcludeLazyInitializationDemoBean.class); ExcludeLazyInitializationBean.writer("third bean"); } }
- 実行結果
>gradlew bootRun > Task :bootRun call constructor lazyInitializationDemoBean2 call constructor excludeLazyInitializationDemoBean 2019-10-23 18:52:52.464 INFO 6004 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' 2019-10-23 18:52:52.468 INFO 6004 --- [ main] jp.co.musako.Application : Started Application in 2.978 seconds (JVM running for 3.454) Initialize Application Context call constructor lazyInitializationDemoBean1 lazyInitializationDemoBean1 is first bean lazyInitializationDemoBean2 is second bean excludeLazyInitializationDemoBean is third bean上記のように、Config.javaで定義した3つのBeanのうち、lazyInitializationDemoBean1のみがLazyInitializationの対象となることがわかります。
ソースコードはこちら:GitHub - forests-k/spring-boot-lazy-initialization
: Spring Boot v2.2.0 lazy-initialization sampleLazy Initializationの適用時の検討事項
Lazy Intializationを導入するメリットは、アプリケーション起動時の速度が向上すること、必要な時に初期化するため無駄にメモリを消費しないことにあります。
しかし、必要な時にBeanを初期化してコンテナにBeanを保持するということは、これまでのBeanのライフサイクルが一部変更となり、コンテナ内で保持するBeanの最大となりうる数量(=メモリ占有量)がみえないことがあるので、CPUへの負荷やロードアベレージへの影響がある、すなわちLazyInitializationを過信しすぎてはいけない、という可能性があるかもしれないです。
そのため、テスト環境や本番同等の環境で一時的にLazy Initializationを無効化するなどのテストを実施することも視野に入れるべきと思われます。
ref
- 投稿日:2019-10-23T19:25:49+09:00
Spring Boot 2.2.0でLazy Initializationを試してみる
Spring Boot v2.2.0
Spring Boot v2.2.0がリリースされ、GAとなりました。
なので、その機能の一つであるLazyInitializationについて検証してみます。
Spring Boot 2.2.0
Release v2.2.0.RELEASE · spring-projects/spring-boot · GitHub
Spring Boot 2.2 Release Notes · spring-projects/spring-boot Wiki · GitHub
Spring Boot Reference Documentation環境
- Windows10
- OracleJDK 13(build 13)
- Spring Boot 2.2.0 RELEAS
Projectの作成
ひながたとなるProjectは、Spring Initializrから作成します。
Gradle
Spring Initializrで作成したGradleプロジェクトでは、Gradle 5.6.2が適用されることを確認しました。
> gradlew -version ------------------------------------------------------------ Gradle 5.6.2 ------------------------------------------------------------ Build time: 2019-09-05 16:13:54 UTC Revision: 55a5e53d855db8fc7b0e494412fc624051a8e781 Kotlin: 1.3.41 Groovy: 2.5.4 Ant: Apache Ant(TM) version 1.9.14 compiled on March 12 2019 JVM: 13-ea (Oracle Corporation 13-ea+33) OS: Windows 10 10.0 amd64lazy-initialization
ApplicationContextで管理するBeanの生成を、アプリケーションの起動時(≒ApplicationContextの初期化時)ではなくて、対象のBeanの呼び出しがされる際に行うのが、Lazy Initializationです。
この機構は以前のバージョンからもありますが、v2.2.0からはproperty
spring.main.lazy-initializationにtrueを適用することで、一律LazyInitializationが適用されます。
- application.yml
spring: main: lazy-initialization: true
- Bean class
package jp.co.musako.domain.model; public class LazyInitializationDemoBean { private String message; public LazyInitializationDemoBean(String message) { this.message = message; System.out.println("call constructor " + this.message); } public void writer(String message){ System.out.println(this.message + " is " + message); } }
- config class
package jp.co.musako.config; import jp.co.musako.domain.model.LazyInitializationDemoBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class Config { @Bean("lazyInitializationDemoBean1") public LazyInitializationDemoBean lazyInitializationDemoBean1(){ return new LazyInitializationDemoBean("create lazyInitializationDemoBean1"); } @Bean("lazyInitializationDemoBean2") public LazyInitializationDemoBean lazyInitializationDemoBean2(){ return new LazyInitializationDemoBean("create lazyInitializationDemoBean2"); } }
- main class
package jp.co.musako; import jp.co.musako.domain.model.LazyInitializationDemoBean; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ApplicationContext; @SpringBootApplication public class Application { public static void main(String[] args) { ApplicationContext ctx = SpringApplication.run(Application.class, args); System.out.println("Initialize Application Context"); LazyInitializationDemoBean bean1 = ctx.getBean("lazyInitializationDemoBean1", LazyInitializationDemoBean.class); bean1.writer("first bean"); LazyInitializationDemoBean bean2 = ctx.getBean("lazyInitializationDemoBean2", LazyInitializationDemoBean.class); bean2.writer("second bean"); } }実行結果
>gradlew bootRun > Task :bootRun 2019-10-23 18:16:37.620 INFO 12708 --- [ main] jp.co.musako.Application : Started Application in 4.295 seconds (JVM running for 4.933) Initialize Application Context call constructor lazyInitializationDemoBean1 lazyInitializationDemoBean1 is first bean call constructor lazyInitializationDemoBean2 lazyInitializationDemoBean2 is second beanここで、以下の順序で処理がされていることがわかります。
- アプリケーション起動
- 起動後に「Initialize Application Context」を出力
- Beanの生成
- Beanのコンストラクタ内で「call constructor lazyInitializationDemoBean1」を出力
- 生成したBeanのwriterメソッドが呼び出される
- writerメソッドで「lazyInitializationDemoBean1 is first bean」を出力
Lazy Initializationの適用除外
spring.main.lazy-initialization=trueを設定してLazyInitializationをプロジェクトに適用しつつ、特定のBeanをLazyInitializationの対象外とするには以下の方法があります。
@org.springframework.context.annotation.Lazy(false)をBeanに設定するorg.springframework.boot.LazyInitializationExcludeFilterに対象外とするBeanを登録する
- config class
package jp.co.musako.config; import jp.co.musako.domain.model.ExcludeLazyInitializationDemoBean; import jp.co.musako.domain.model.LazyInitializationDemoBean; import org.springframework.boot.LazyInitializationExcludeFilter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; @Configuration public class Config { @Bean static LazyInitializationExcludeFilter integrationLazyInitExcludeFilter() { return LazyInitializationExcludeFilter.forBeanTypes(ExcludeLazyInitializationDemoBean.class); } // Lazy Initialization適用対象 @Bean("lazyInitializationDemoBean1") public LazyInitializationDemoBean lazyInitializationDemoBean1(){ return new LazyInitializationDemoBean("lazyInitializationDemoBean1"); } // Lazy Initialization適用対象外 @Bean("lazyInitializationDemoBean2") @Lazy(false) public LazyInitializationDemoBean lazyInitializationDemoBean2(){ return new LazyInitializationDemoBean("lazyInitializationDemoBean2"); } // Lazy Initialization適用対象外 @Bean public ExcludeLazyInitializationDemoBean ExcludeLazyInitializationDemoBean(){ return new ExcludeLazyInitializationDemoBean("excludeLazyInitializationDemoBean"); } }
- 実行結果
>gradlew bootRun > Task :bootRun call constructor lazyInitializationDemoBean2 call constructor excludeLazyInitializationDemoBean 2019-10-23 18:52:52.464 INFO 6004 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' 2019-10-23 18:52:52.468 INFO 6004 --- [ main] jp.co.musako.Application : Started Application in 2.978 seconds (JVM running for 3.454) Initialize Application Context call constructor lazyInitializationDemoBean1 lazyInitializationDemoBean1 is first bean lazyInitializationDemoBean2 is second bean excludeLazyInitializationDemoBean is third bean上記のように、Config.javaで定義した3つのBeanのうち、lazyInitializationDemoBean1のみがLazyInitializationの対象となることがわかります。
ソースコードはこちら:GitHub - forests-k/spring-boot-2.2.0: Spring Boot v2.2.0 sample
Lazy Initializationの適用時の検討事項
Lazy Intializationを導入するメリットは、アプリケーション起動時の速度が向上すること、必要な時に初期化するため無駄にメモリを消費しないことにあります。
しかし、必要な時にBeanを初期化してコンテナにBeanを保持するということは、これまでのBeanのライフサイクルが一部変更となり、コンテナ内で保持するBeanの最大となりうる数量(=メモリ占有量)がみえないことがあるので、CPUへの負荷やロードアベレージへの影響がある、すなわちLazyInitializationを過信しすぎてはいけない、という可能性があるかもしれないです。
そのため、テスト環境や本番同等の環境で一時的にLazy Initializationを無効化するなどのテストを実施することも視野に入れるべきと思われます。
ref
- 投稿日:2019-10-23T18:28:33+09:00
「基本からしっかり身につくAndroidアプリ開発入門」やってみた
基本からしっかり身につくAndroidアプリ開発入門
はじめに
やあ、大学の課題地味に多くて忙しいのであるが、時間が余ってもどうせしょうもないことにしか時間を使わないので、何かをしようと思った私だ。いや誰だ。俺か。
ちなみに、大学ではいつも一人です(ぼっち自慢)。超どうでも良い(笑)。
前述した通り暇だからなんかしようと考えたのである。
大学の図書館にある技術書を読み漁りつつ評価とメモをqiitaに書いていく。
ということを思いついて、今回手にしたのは重厚で現代的な表紙の「Androidアプリ開発入門」だ。
すでにRuby on Railsでなんちゃって開発はできるので、アプリ開発もできたら、サービスを展開する時幅が広がるので時間を削って学習するメリットはあると考えた。内容
開発環境
- OS:(俺は)Mac
- 言語:Kotlin
- 使用ソフト:Android Studio
chapter1
Android studioのインストールから開発環境設定まで。
chapter2
Kotlinの書き方基礎
- 変数と型の宣言
- 配列、リスト、マップ
- 条件式(if,when)とレンジ
- 繰り返し文(while)
- 関数(デフォルト引数、可変長引数...etc)
- クラス...etc
chapter3
計算機アプリ(割引計算アプリ)を作る。
AndroidStudioにLabelForがないこと以外は、非常によい掴みになっている。
- ファイル構造の把握
- GUIの作り方
- システムの作り方
- 画面遷移のやり方
- 多言語対応、デバックのやり方...etc
chapter4
データの保存とデータベースの使いかた。
SharedPreferences/リストビューchapter5
世界時計アプリを作る。
chapter6
アプリの通信とバックグランドでの処理について。
(Thred/Handler/AsyncTask...etc)
リサイクラービューchapter7
外部ストレージ
chapter8
デプロイ
つまづいたところ
chapter3 - activity_main.xml
アプリのヘッダーの部分が表示されない。
1.目のマークをクリック
2.全てにチェックを入れる。chapter4 - 文字列リソースの定義
view all attributesを開いてもlabelForの欄がない。
chapter5 -リストビュー用ミニアプリ
レイアウトファイルを作る時、Root elementを
androidx.constraintlayout.widget.ConstraintLayoutすることに注意!!textClockがPaletteを選ぶ場所になかったので
DesignタブからTextタブに切り替えて、下のソースコードを追加。<TextClock android:id="@+id/textClock" android:layout_width="173dp" android:layout_height="89dp" android:textSize="64sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.100000024" tools:text="10:00" />エラー文を見ると「TextClockが使えるバージョンにしよう」みたいなことを言われるので、
v17/activity_main.xmlかactivity_main.xml(v17)のファイルの生成を要求されるので従う。
次からはv17/activity_main.xmlactivity_main.xml(v17)のファイルを編集する。chapter6-リサイクラー用ミニアプリ
RecyclerViewをDesignタブのAttributeタブで編集できない。
Textタブに切り替えて、
android:id="@+id/timeZoneList"
をタグの中に追加
layout_width,layout_heightも同様。感想
Kotlin書籍1冊目だから比較ができないが、非常に読みやすいと感じた。
特にクラスや関数、メソッドあたりが自分の中でごちゃごちゃしていたので、こんなかんじで設計したり使ったりするんだなーってのがわかった。
また、スクリーンショットが複数あるので、基本的にストレスなくスムーズに進めながらアプリ開発の基礎を理解することができた気がする。
しかし、メソッドが豊富に使われているので記憶が定着しているうちに読み進めるか、何周かしたほうがいいと考える。
よかったところ
- Kotlinの基本文法の解説が詳しい。また、それぞれのコードの例とその結果が文法理解に役立つ。
- コードの例が豊富
- 文法解説は簡潔でわかりやすいと感じた(主観)
- 小物アプリ開発のtutorialが複数用意されている。また、常にスクリーンショットが用意されており開発GUI操作でつまづかない
- 複数のアプリ開発でフローを理解できる
- 初心者でもとっつきやすい
よくなかったところ
- Android StudioのGUIが書籍のスクリーンショットと少し差異がある。(しょうがない)
- 書籍が分厚い(しょうがない)
- なんでかしらんけどlabelForがAttributeにない。
- 投稿日:2019-10-23T17:25:04+09:00
[Java]Stringクラスを使って特定の文字列の手前までを取得する方法
文字列の取得の方法としてメモ書き。
Stringクラスには、最初に出現する文字列を取得する場合にはindexOfメソッドを、最後に出現する文字列を取得する場合はlastIndexOfメソッドを使用することで特定の文字列を取得することができる。
基本的な書き方はこんな感じ。
最初に出現する位置 = オブジェクト.indexOf(値)
最後に出現する位置 = オブジェクト.lastIndexOf(値)
今回はStringクラスでの使用方法についてまとめてみる。
⑴indexOfメソッド
・indexOf(int ch)
(戻り値の型はint)この文字列内で、指定された文字が最初に出現する位置のインデックスを返します。値chを持つ文字がこのStringオブジェクトによって表される文字シーケンス内にある場合、最初に出現する位置のインデックス(Unicodeコード単位)が返されます。chの値が0から0xFFFFの範囲にある場合、次の式がtrueとなるような最小値kが返されます。
this.charAt(k) == ch
がtrueである。chがほかの値の場合、次の式がtrueとなるような最小値kです。
this.codePointAt(k) == ch
がtrueである。該当する文字がこの文字列内にない場合は、-1が返されます。
パラメータ:
ch - 文字(Unicodeコード・ポイント)。
戻り値:
このオブジェクトによって表される文字シーケンス内で、指定された文字が最初に出現する位置のインデックス。文字がない場合は-1。・indexOf(int ch, int fromIndex)
(戻り値の型はint)
この文字列内で、指定されたインデックスから検索を開始し、指定された文字が最初に出現する位置のインデックスを返します。
値chを持つ文字が、このStringオブジェクトによって表される文字シーケンスのfromIndexより大きいか同じインデックス位置にある場合、該当する最初のインデックスが返されます。chの値が0から0xFFFFの範囲にある場合、次の式がtrueとなるような最小値kが返されます。
(this.charAt(k) == ch) && (k >= fromIndex)がtrueである。chがほかの値の場合、次の式がtrueとなるような最小値kです。
(this.codePointAt(k) == ch) && (k >= fromIndex)がtrueである。いずれの場合も、そのような文字がこの文字列内の位置fromIndexかそれより後に存在しない場合は、-1が返されます。
fromIndexの値に対して制約はない。負の値の場合は、ゼロの場合と同じ結果になります。この文字列全体が検索されます。この文字列の長さより大きい場合は、この文字列の長さに等しい場合と同じ結果になり、-1が返されます。
すべてのインデックスは、char値(Unicodeコード単位)で指定されます。
パラメータ:
ch - 文字(Unicodeコード・ポイント)。
fromIndex - 検索開始位置のインデックス。
戻り値:
このオブジェクトによって表される文字列で、指定された文字がfromIndexと同じかこれより大きいインデックス位置にある場合は、最初に出現した位置のインデックス。文字がない場合は-1。(2)lastIndexOfメソッド
・lastIndexOf(int ch)
この文字列内で、指定された文字が最後に出現する位置のインデックスを返します。ch値が0から0xFFFFの範囲にある場合、返されるインデックス(Unicodeコード単位)は、次の式に該当する最大値kです。
this.charAt(k) == ch
がtrueである。chがほかの値の場合、次の式がtrueとなるような最大値kです。
this.codePointAt(k) == ch
がtrueである。該当する文字がこの文字列内にない場合は、-1が返されます。Stringの検索は最後の文字から開始され、先頭方向に行われます。
パラメータ:
ch - 文字(Unicodeコード・ポイント)。
戻り値:
このオブジェクトによって表される文字シーケンス内で、指定された文字が最後に出現する位置のインデックス。文字がない場合は-1。・lastIndexOf(int ch, int fromIndex)
(戻り値の型はint)この文字列内で、指定された文字が最後に出現する位置のインデックスを返します(検索は指定されたインデックスから開始され、先頭方向に行われる)。ch値が0から0xFFFFの範囲にある場合、返されるインデックスは、次の式に該当する最大値kです。
(this.charAt(k) == ch) && (k <= fromIndex)
がtrueである。chがほかの値の場合、次の式がtrueとなるような最大値kです。
(this.codePointAt(k) == ch) && (k <= fromIndex)
がtrueである。いずれの場合も、そのような文字がこの文字列内の位置fromIndexかそれより前に存在しない場合は、-1が返されます。
すべてのインデックスは、char値(Unicodeコード単位)で指定されます。
パラメータ:
ch - 文字(Unicodeコード・ポイント)。
fromIndex - 検索開始位置のインデックス。fromIndexの値に対して制約はない。この文字列の長さと同じかこれより大きい場合は、この文字列の長さより1小さい場合と同じ結果になり、この文字列全体が検索される。負の値の場合は、-1の場合と同じ結果になり、-1が返される。
戻り値:
このオブジェクトによって表される文字シーケンス内で、指定された文字がfromIndexと同じかこれより小さいインデックス位置に最後に出現する位置のインデックス。指定された文字がその位置より前にない場合は-1。参考サイト
・Java(tm) Platform Standard Edition 8 クラスString
https://docs.oracle.com/javase/jp/8/docs/api/index.html?overview-summary.html・すぐに使える!JavaのindexOfとlastIndexOf - エンジニアの入り口
https://eng-entrance.com/java-indexof
- 投稿日:2019-10-23T16:32:40+09:00
Spring Bootを触ってみたメモ
Spring Bootの特徴
兎に角、アノテーションによって他の言語と同じようにサーブレットの存在を無視したプログラミングができるようになっていることが大きな特徴なよう。
アノテーション 概要 @ Conponent DIコンテナにBeanとして登録する最も基本的なアノテーション @ Configuration Bean定義をJavaベースで行うためのアノテーション ※言っている意味わからないので後ほど解説 @ Repository データの保存や読み込みなどを扱うためのクラスを示すアノテーションです。Spring Dataなど使いデータベースを利用する場合には、このアノテーションを指定することで自動的にテーブルにアクセスできるようにするなど、特別な意味を持つケースがあります。 @ Controller MVCのコントローラークラスであることを示すアノテーション。 @ Service ビジネスロジックなどを扱うためのクラスを示すアノテーション。 各サブプロジェクトで特別なものとして、これらのアノーテーションを上書きして別のアノテーションが定義される。
アノテーション 概要 @ SpringBootApplication Spring Bootのアプリケーションのmainプログラムを指定するための慣習として利用されるアノテーション @ RestController REST用のコントローラとして登録するためのアノテーション @ RestControllerAdvice 各コントローラで共通の入力データ形式の変換やエラー処理などの共通処理を定義するためのアノテーション。 ※コーディングの際は@ と アノテーション名の間にはスペース不要
- mavenを利用する場合
pom.xlmファイルに依存関係のパッケージを記載すると自動的に必要なパッケージを読み込んでくれるapplication.properties各パッケージで使用する設定をまとめて記載する場所- gradleを利用する場合
- これから使ってみる予定
Entity周りのアノテーション概要
https://qiita.com/ughirose/items/5d691adc677aa08636b8
Spring Bootログ周りの設定概要
https://qiita.com/NagaokaKenichi/items/34356c72e8ac0279e1a0
RestAPI作成時の記載方法
https://qiita.com/MizoguchiKenji/items/2a041f3a3eb13274e55c
JpaRepositoryの使い方
http://terasolunaorg.github.io/guideline/5.5.1.RELEASE/ja/ArchitectureInDetail/DataAccessDetail/DataAccessJpa.html
さらに条件を加えて検索したいときの利用方法
https://qiita.com/ksh-fthr/items/44ecc0550a77f4280ea7
- 投稿日:2019-10-23T06:40:38+09:00
Java 単体テスト 同一日判定 ArDate,Date,Calendar,longが時刻を無視して同一日かを判定する
目次 ⇒ Java単体テストライブラリ-Artery-サンプル
Q05_02.javapackage jp.avaj.lib.test; import java.util.Date; import jp.avaj.lib.algo.ArDate; import jp.avaj.lib.algo.ArDateUtil; /** Java 単体テスト 同一日判定 ArDate,Date,Calendar,longが時刻を無視して同一日かを判定する ・このサンプルではArDateとDateを比較するサンプル示すが、上記のどの組み合わせでも比較可能. ・注、ArDateは日付のみを保持しており、時刻は扱わない. */ public class Q05_02 { public static void main(String[] args) { // テストケースを開始する. ArTest.startTestCase("Q05_02"); // 当日 ArDate arDate0 = new ArDate(); // 当日、当時刻 Date date1 = new Date(); // これを比較すれば同一日 ArTest.sameDate("ArDate vs Date","arDate0",arDate0,"date1",date1); // date1を一時間進める、引数は日→時間→分の指定、このメソッドはCalendar,longでも使用可能. date1 = ArDateUtil.forward(date1,0,1,0,0); // (このテストを23時以前に実行すれば)同一日となる ArTest.sameDate("ArDate vs Date","arDate0",arDate0,"date1",date1); // arDate0を一日進める arDate0.forward(1); // 両方を比較すれば、同一日ではない ArTest.notSameDate("ArDate vs Date","arDate0",arDate0,"date1",date1); // date1を一日進める、 date1 = ArDateUtil.forward(date1,1,0,0,0); // 再び同一日となる ArTest.sameDate("ArDate vs Date","arDate0",arDate0,"date1",date1); // // テストケースを終了する ArTest.endTestCase(); } }結果は次の通り
result.txt**** Q05_02 start **** OK ArDate vs Date:arDate0=2019/10/23:date1=2019/10/23 06:37:09 OK ArDate vs Date:arDate0=2019/10/23:date1=2019/10/23 07:37:09 OK ArDate vs Date:arDate0=2019/10/24:date1=2019/10/23 07:37:09 OK ArDate vs Date:arDate0=2019/10/24:date1=2019/10/24 07:37:09 **** Q05_02 summary **** test count = 4 success = 4
- 投稿日:2019-10-23T01:21:09+09:00
Windows 版 Amazon Corretto インストール手順
Windows 版 OpenJDK インストール手順 - Qiita の二番煎じ。
調べ方
- amazon corretto - Google Search
- windows ライフサイクル site:microsoft.com - Google 検索
- エクスプローラー アドレスバー - Google 検索
前提
- サポートされている Windows であること。
備考
- 新しいバージョンの OpenJDK をダウンロード, 展開した場合は, JAVA_HOME の変数値を変更するだけで OK.
- Path は
%JAVA_HOME%\binのままとする。インストール手順
- Amazon Corretto Production-ready distribution of OpenJDK にアクセスする。
- 日本語版のサイトは情報が古い場合があるため, 画面上部より English を選択する。
- 画面右の Download Amazon Corretto 11 ボタンを押下する。
- Downloads for Amazon Corretto 11 - Amazon Corretto に遷移する。
- 先ほどと同様, 日本語版のサイトは情報が古い場合があるため, 画面上部より English を選択する。
- Windows x64 の JDK に記載された zip ファイルをクリックする。
- 今回は amazon-corretto-11.0.5.10.1-windows-x64.zip をクリックしたものとする。
- ダウンロードしたファイルを右クリックし, すべて展開 をクリックする。
- 圧縮 (ZIP 形式) フォルダーの展開 ウィンドウが開く。
- ファイルを下のフォルダーに展開する 欄に,
C:\と入力し, 展開 ボタンを押下する。
- 上記は, OS やブラウザーによってはコロン (
:) の次にバックスラッシュが表示される場合があるが, 日本語キーボードの場合は円記号で OK.- C ドライブ直下に,
jdk11.0.5_10というフォルダーが展開される。- ダウンロードしたファイルを削除する。
- 展開したフォルダーに移動し, アドレスバーよりパスをコピーする。
- 今回のパスは
C:\jdk11.0.5_10となる。- スタート - 設定 を開く。
- Windows の設定 ウィンドウが表示される。
- 検索窓に
環境変数と入力する。
- 環境変数を編集 と システム環境変数の編集 が候補として表示される。
- 環境変数を編集 をクリックする。
- 環境変数 ウィンドウが表示される。
- ユーザー環境変数 の 新規 ボタンを押下する。
- 新しいユーザー変数 ウィンドウが表示される。
- 以下の通りに入力し, OK ボタンを押下する。
- 変数名: JAVA_HOME
- 変数値: (先ほどコピーしたパスを貼り付ける。)
- 今回の場合は
C:\jdk11.0.5_10を貼り付けることになる。- 環境変数 ウィンドウに戻るので, ユーザー環境変数 の Path をクリックし, 編集 ボタンを押下する。
- 環境変数名の編集 ウィンドウが表示される。
- 新規 ボタンを押下し,
%JAVA_HOME%\binと入力, OK ボタンを押下する。
- 環境変数 ウィンドウに戻る。
- そのまま OK ボタンを押下する。
- Windows の設定 ウィンドウは閉じても OK.
コマンドプロンプトを開き,
javaやjavacコマンドが利用できることを確認する。
> java -versionopenjdk version "11.0.5" 2019-10-15 LTS OpenJDK Runtime Environment Corretto-11.0.5.10.1 (build 11.0.5+10-LTS) OpenJDK 64-Bit Server VM Corretto-11.0.5.10.1 (build 11.0.5+10-LTS, mixed mode)
> javac -versionjavac 11.0.5どっとはらい。



