JAVA関連のことを調べてみた

JAVA関連のことを調べてみた

直近の開発で気になったことと解決策

# 1. 前段
とあるよわよわIT企業に所属していて、Java(Springboot)+Mybatis+MySQLで新しいシステムを立ち上げました。私自身は、プロジェクトマネージャーで必要な業務要件を理解しつつ、コードも書けるタイプです。(ただし、Springbootのフレームワークはあまり詳しく無いため、詳しい人に助けてもらいながら開発してきました。)

そして今現在、システム稼働から1年以上経過したところで、気づいたら技術負債がかなりたまってしまいました。
私としても失敗して初めて気づいたこともあったので、将来同じ失敗をしないために、ここにメモをします。

もし気づいたことや意見があれば、コメントいただけると助かります!

# 2. 「とりあえず」で作ってしまったけど必要なかった

## (1) 削除フラグ(関連:SQLアンチパターン幻の第26章)

### 課題
参考のスライド内でもいろいろ書かれているが、私が困ったのは主に以下の2点。
– SELECT時に削除フラグをWHERE条件内に書き忘れる。結局、システム全体で削除フラグが正しく動作することの保証ができない。
– ほとんど

元記事を表示

Javaのラッパークラスについて

## はじめに
Javaのラッパークラスは、基本データ型(プリミティブ型)をオブジェクトとして扱うためのクラスです。これらのクラスは、Javaのコアライブラリで提供されており、プリミティブ型をオブジェクトとして使用する必要がある場合に役立ちます。この記事では、ラッパークラスの概要、各ラッパークラスの説明、使用方法、オートボクシングとアンボクシング、そしてラッパークラスの利点と欠点について見ていきます。

## ラッパークラスの概要

Javaには、次の基本データ型があります:

– `byte`
– `short`
– `int`
– `long`
– `float`
– `double`
– `char`
– `boolean`

これらの基本データ型には、それぞれ対応するラッパークラスがあります:

| プリミティブ型 | ラッパークラス |
| ————– | ————– |
| `byte` | `Byte` |
| `short` | `Short` |
| `int`

元記事を表示

(java gold)Set

## Set

* 重複した要素を含むことができないコレクション
* 順序があるとは限らない

* Setを継承したクラス
1. `HashSet`: 値の重複を許さない順不同の要素集合を扱います
2. `TreeSet`: 値の重複を許さないソートされた要素集合を扱いま

## Setのメソッド
### 追加
| メソッド名 | 概要 |
|:–|:–|
set.add(o) | オブジェクト o を配列の末尾に追加する

### 削除
| メソッド名 | 概要 |
|:–|:–|
set.remove(o) | オブジェクト o にマッチする要素を削除する
| set.clear() | 配列をクリアする |

### 取得
:::note warn
メソッドは用意されていない
:::

### 要素数
| メソッド名 | 概要 |
|:–|:–|
|`list.size()` | 要素の個数を得る|

元記事を表示

(java gold)List

## List

* 順序付けられたコレクション。重複した要素を含むことができる、ユーザーは要素を挿入する場所やインデックスによって要素にアクセスすることを正確に制御できる

* Listはインターフェースなのでインスタンは生成できない

* Listのメリットはコレクション(データ型)に変更したい場合、宣言時に手を加えなくていい

* ListのデメリットはArrayListにしかメソッドがないときにキャストしなければならない

* Listは以下のクラスで実装されています
1. `ArrayList`: 配列を扱う一般的なクラス
2. `LinkedList`: 要素がどのように並んでいるか別で管理しているために要素を削除したり追加する場合にArrayListよりも高速に動作するが、要素を順にたどるため検索などはArrayListよりも遅くなる
3. `Vector` : ArrayList や LinkedList と同じように扱うことができますが、同期をとるためパフォーマンスが悪い(スレッドセーフ)
4. Stack

元記事を表示

(java gold) Deque

## Deque

* 後に入れたデータを先に取り出す仕組みのLIFO(Last In First Out)を使うためのもの
* 先に入れたものを先に取り出す仕組みはキュー(Queue)、FIFO(First In First Out)と呼ばれます
* Dequeの実装クラスは
1. `ArrayDeque`: 挿入、削除、取得を両端でしか行わない場合、ArrayDequeのほうが高速に動作
1. `LinkedList`: 配列の中間にアクセスする場合(containsやindexOfなど)は、LinkedListのほうが速い

### 追加
| メソッド名 | 概要 |
|:–|:–|
| queue.addFirst(o) | oをデックの先頭に追加する(エラー時は例外を返す)
| queue.addLast(o) | oをデックの最後に追加する(エラー時は例外を返す) |
queue.offerFirst(o) | oをデックの先頭に追加する(エラー時はfalseを返す)
queue.offerLast(o) | oをデックの最後に追加する(エラー時はfa

元記事を表示

(java gold) 並列処理

## スレッド
* `スレッド`とはプログラムを実行した場合の最小単位
* プログラムの実行単位を複数のスレッドに分割して実行することを`マルチスレッド`
* スレッドの制御には`java.lang.Threadクラス`と`java.lang.Runnableインターフェース`を使用

## スレッドの実行
* Runnable.run()メソッド
* Thread.start()メソッド
* start()メソッドの中ではオーバーライドしたrun()メソッドの呼び出しを行っている

:::note warn
スレッド処理の開始はstart() メソッドだが
(run()メソッドを直接呼び出してもスレッドは開始されない)
:::

## スレッドの優先度
* 優先度を取得・設定するメソッド

| メソッド名 | 概要 |
|:–|:–|
| static Thread currentThread| 現在実行中のスレッドオブジェクトを取得する |
| final String getName() | スレッドの名前を返す |
| final int getPriority

元記事を表示

(java gold) ストリームAPIの生成

## ストリームAPI(StreamAPI)
* 繰り返し処理をサポートするライブラリ
* コレクション、配列、ファイルなどのデータの集合(データソース)から要素を取り出し処理の流れ(Stream)に引き渡す。

* `中間処理` : 戻り値はStream
* `終端処理` : 終端処理のタイミングでうとりーむ一連の処理が実行される
* メソッドチェーン : ストリーム生成から中間処理/終端演算子.演算子で連結できる

## リスト・マップ

“`java
//リスト
var list = new ArrayList(
Arrays.asList(“ant”, “elephant”, “hamster”));
list.stream()
.forEach(System.out::println);
// 並列処理
list.parallelStream().forEach(System.out::println);

//マップ
var map = new

元記事を表示

(java gold) Collector

## Collector

ストリームのリダクション操作のためのインターフェースであり、処理途中のオブジェクトを適切に扱うことができる。

“`java
public interface Collector {
Supplier supplier();
BiConsumer accumulator();
BinaryOperator
combiner();
Function finisher();
Set characteristics();
}
“`
* T : ストリームないの要素の型
* A : 処理途中の値を保持するためのオブジェクト
* R : 最終結果の型
* supplier() : 処理途中の値を保持するためのオブジェクトを生成する
* accumulator() : 具体的に実行したい処理を記述したBiConsumer型のラムダ式を返す
* combiner() : 二つの部分結果を結合する(並行処理時に使用される)
* finisher

元記事を表示

(java gold) mapメソッド

## map

* ストリーム内の要素を別の値に変更する際に使用
* 基本的な構文は以下の通りである

“`java
stream.map(function)
“`

* stream : 元のストリームを表す
* map()メソッド : Function型の引数を受け取る
* function : 各要素を変更するための関数

“`java
List numbers = Arrays.asList(1, 2, 3, 4, 5);
List doubledNumbers = numbers.stream()
.map(number -> number * 2)
.collect(Collectors.toList());
“`

numbersという整数のリストを作成し、mapメソッドを使って各要素を2倍に変換している。この場合、ラムダ式number -> number * 2がFunctio

元記事を表示

(java gold) Comparableインタフェース

## Comparableインターフェースとは

下記はAPIドキュメント
>public interface Comparable
このインタフェースを実装する各クラスのオブジェクトに全体順序付けを強制します。この順序付けはクラスの自然順序付けと呼ばれ、このクラスのcompareToメソッドは自然比較メソッドと呼ばれます

Javaのクラスが自然な順序付けをサポートするために実装するインタフェースである。自然な順序付けとは、オブジェクト間の大小関係を定義することを意味する。

位置付けとしてはクラス(オブジェクト)の共通メソッドであるがequalsやtoStringなどと違い、他と違ってComparableはObjectには宣言されていない。

必要に応じてクラス作成時に実装し、抽象メソッドであるcompareTo()メソッドをオーバーライドしなければならない。このメソッドは、自身のオブジェクトと引数として与えられた他のオブジェクトとの比較結果を返す

:::note warn
Comparableを実装せずに自然順序付けに従ってソート実行しようとすると”ClassCastExcep

元記事を表示

(java gold) Comparatorインターフェース

## Comparator
APIドキュメントより
>オブジェクトのコレクションで全体順序付けを行う比較関数です。コンパレータ(Comparator)をソート・メソッド(Collections.sortやArrays.sortなど)に渡すと、ソート順を正確に制御できます。また、コンパレータを使用すると、sorted sets (ソート・セット)やsorted maps (ソート・マップ)などの特定のデータ構造の順序を制御したり、natural ordering (自然順序付け)を持たないオブジェクトのコレクションに順序付けを提供したりすることもできます。

Javaのクラスがオブジェクトの比較方法をカスタマイズするために実装するインタフェースである。主な目的は、自然な順序付けが定義されていないクラスのオブジェクトを比較するために使用される。
### Compararのメソッド

* compare(T o1, T o2)
順序付けのために2つの引数を比較します。

* 負の整数:
o1 は o2 よりも小さいと判断される。
* 0:
o1 と o2 は等しいと判断される。

元記事を表示

(java gold) Collectorsクラス

# Collectorsについて
下記APIリファレンスより
>要素をコレクションに蓄積したり、さまざまな条件に従って要素を要約するなど、有用な各種リダクション操作を実装したCollector実装。

# 主なメソッド

* 集約

| メソッド名 | 概要 |
|:–|:–|
|toList()|要素をリストに集約する|
|toSet() |要素をセットに集約する|
|toMap()|キーと値のペアに要素を集約する|

* グループ化

| メソッド名 | 概要 |
|:–|:–|
|groupingBy()|指定したキーで要素をグループ化する|
|partitioningBy()|指定した条件に基づいて要素をパーティション分割する|

* 変換

| メソッド名 | 概要 |
|:–|:–|
|mapping() | 要素を指定した関数によって変換する|
|reducing()|要素をリダクション(まとめる)操作によって変換する|

* 統計

| メソッド名 | 概要 |
|:–|:–|
|summarizingXxx()|指定した数値型の統計情報を収集|
|av

元記事を表示

(java gold) flatmap

## flatmap
Optionalオブジェクトが値を保持している場合に、その値を別のOptionalオブジェクトに変換するためのメソッドである。変換されたOptionalオブジェクトが返される。

flatMap()メソッドは、以下のようなシグネチャを持っている。

“`java
Optional flatMap(Function> mapper)
“`

# mapとflatmapの比較

### 戻り値の比較

* map()メソッドはOptionaalであり変換操作によって得られた値を新しいOptionalオブジェクトとして戻す。
* flatmap()メソッドは値の変換操作によって得られたOptionalオブジェクトを自動的に解消しフラットなOptionalを戻す。

## 使い分け
### map()メソッド:
* 単純な値の変換を行いたい場合
* 変換操作自体をスキップせずに実行したい場合
### flatMap()メソッド
* 値の変換によってネストしたOptionalオブジェクトを解消した

(java gold) インターフェース

## インターフェース

### staticメソッド
* 実装を持つstaticメソッド
* オーバーロード不可(継承されない)
### デフォルトメソッド
* defaultキーワードを持つ実装メソッド
* インターフェースメソッドがオーバーライドされない場合の実装を提供
* デフォルトメソッドの解決ルール
* スーパークラス>インターフェース
(あくまでインターフェースは型を提供している)
* サブタイプ>スーパータイプ
* 競合したら実装クラスでオーバーライド

### プライベートメソッド
* privateな実装メソッド
* インターフェース内からのみ呼び出せる
 =デフォルトメソッドから呼び出せる

(java gold) enum

# enum(イーナム)の宣言
### 構文
“`java
enum EnumName {
CONSTANT1,
CONSTANT2,
// …
}
“`
* `enum` :列挙型の宣言
* `EnumName` :列挙型の名前
* `CONSTANT1` :列挙型の定数。定数は大文字で記述されカンマ区切り、特定の値を持つ

* enumは外部からインスタンス化できない(定数として使える)
#### switch文で使用可能
* caseは定数で指定する下記コードでは(R,G,B)
“` java
public class Test {
public static void main(String… args) {
new Test().check(GRADE.A);
}
void check(GRADE grade) {
switch (grade) {
case A:
System.out.println(“Best”); brea

(java gold) クラス

## 内部クラス(インナークラス)

* エンクロージングインスタンスのprivateフィールドにアクセス可能
* ネストしたクラスにはインナークラス、staticインナークラス、ローカルクラス、匿名クラスがある。
* ローカルクラスは、メソッド内で定義されるクラスのことで、abstract, finalで修飾できる。
* 匿名クラスはあらゆる修飾子を使用することはできない。
* インナークラスのインスタンスを生成するには、エンクロージングクラスのインスタンスを先に生成する必要がある。
“`java 
new Outer().new Inner()
“`
* staticインナークラスはエンクロージングクラスのインスタンス化は不要。
“`java
new Inner(), new Comparator()など
“`
* ローカルクラスから参照するローカル変数は、ローカルクラスよりもあとにローカル変数を宣言すると`コンパイルエラー`。また、その時のローカル変数は実質的にfanalでなければならない。(値を変更しようとすると`コンパイルエラー`)
* 匿名クラスには名前がないため

(java gold) コレクションとジェネリクス

## ジェネリクス
* ワイルドカード型…総称型パラメータの変性を変更する仕組み
* ?…非境界ワイルドカード型(型が…不明なのでgetした要素の型はObject型)
* ? extends T … 上限境界ワイルドカード型(少なくてもTのサブクラス: 共変)
* ? super T … 下限境界ワイルドカード型(少なくてもTのスーパークラス: 反変)
* 読み込みには上限境界ワイルドカード型、書き込み時には下限境界ワイルドカード型を使う

“`java
// Point: Java のコレクションは非変なので List
// List には親子関係がないものとみなす。
// (配列の場合は共変なので代入可)つまり、
List li = Arrays.asList(1, 2);
List lo = li; // NG
//となるが、総称型パラメータにワイルドカード型を使うことで
//制約を変更可能
Lust lw = li; // OK
“`

## 命名慣

(java gold) ストリームAPI 中間操作・終端操作

## 中間操作
取り出したストリームの要素に加える処理のこと。フィルタリング、ソートなどの操作がある。
中間操作は、新しいストリームを返し、元のストリームは変更されない。これにより、パイプライン処理を実現し、効率的なデータ操作を行うことができる。

### 中間操作の例

* `distinct()` : ストリーム内の重複した要素を削除する。重複した要素があるときは最初の要素のみが新しいストリームに含まれる
* `filter(Predicate predicate)` : 指定された条件に基づいて要素をフィルタリングする。条件に合致する要素だけ新しいストリームに含まれる
* `map(Function mapper)` : 要素を指定された関数によって変換する。各要素は関数によって変換され変換後に新しいストリームが生成される
* `sorted()` : 要素をデフォルトの順序(自然順序)でソートする。要素がcomparebleインターフェースを実装している場合その順序によってソートされる
* `sorted(Comparator compa

(java Gold) Map

## Map
* Mapはkeyとvalueをセットにしたもの
* インデックスの代わりに任意の変数を要素の値のペアにできる`keyは重複なしである必要がある`がvalueは同じものが複数あっても大丈夫
* HashMapは格納順が管理されないが、TreeMapは順番がキーになっている
* HashMapはkeyとvalueにnullを使用することが可能だがTreeMapは使用できない
* Mapは以下のクラスで実装されています
1. `HashMap`: キーと値の組からなる要素の集合を扱い、キー名が重複する場合は上書きされます
2. `LinkedHashMap` : キーと値の組からなる要素の集合を扱います。設定順序が保証されます
3. `TreeMap`:キーと値の組からなる要素の集合を扱います。キーでソートされています

### 値の取得
* 値の取得にはMapでkeyを指定しgetメソッドを使用

## Mapのメソッド
### 追加
| メソッド名 | 概要 |
|:–|:–|
|`map.put(key, value)` | key-value を設定する

##

(java gold) 例外とアサーション

## try-with-resouces(JavaSE 7~)
* try句で宣言したリソースは自動でクローズされる
* リソースはAutoCloseableである必要がある
* I/Oストリーム,StreamAPI,JDBC API(Connection, Statement)
* リソースは実質的にfinalも指定可能
* リソースをクローズするタイミング
* finally句の処理前
* 複数リソースの場合はオープンしたときの逆順でクローズ
:::note
実質的 final で思い出したいもの
• try-with-resources (Java SE 9)
• 無名クラス (Java SE 8)
• ラムダ式 (Java SE 8)
:::
:::note alert
これらのコードからアクセス可能な変数は実質的
final である必要がある。(実質的 final でなければ
コンパイルエラーになる)
:::

“`java
class MyResource implements AutoCloseable {
@Override