社団法人 電子情報通信学会
THE INSTITUTE OF ELECTRONICS,
INFORMATION AND COMMUNICATION ENGINEERS

信学技報
TECHNICAL REPORT OF IEICE.

イミュータブルクラスを利用する必要性に関する調査〜ハッシュ値を利用するデータ型を対象として〜
橋本

周†

肥後

芳樹†

楠本

真二†

† 大阪大学大学院情報科学研究科
E-mail: †{shu-hsmt,higo,kusumoto}@ist.osaka-u.ac.jp
あらましJava には複数のオブジェクトを格納するためのさまざまなデータ型が用意されている．その中に，HashMap

や HashSet のように格納するオブジェクトのハッシュ値を利用するデータ型がある．このようなハッシュ値を利用する
データ型は，オブジェクトを格納する際にそのオブジェクトのハッシュ値をデータ型の内部に記録する．そのため，格納されたオブジェクトに変更が加わりハッシュ値が変化してしまった場合に，変更後のハッシュ値とデータ型に記録されたハッシュ値との間で不整合が生じてしまう．そこで，このようなハッシュ値を用いるデータ型に格納するオブジェク
トのクラスにはその内部状態が生成後に変化しないイミュータブルクラスが推奨されている．しかし，イミュータブル
クラスの利用により，ハッシュ値との不整合がどの程度防げているのかについてはこれまで明らかにされてこなかった．
そこで本研究では，Java の実プロジェクトにおいてハッシュ値を利用する HashMap と HashSet を対象とした調査を行い，データ型に格納するオブジェクトはイミュータブルクラスにすべきかを明らかにする．HashMap および HashSet に格納された対象プロジェクト内で定義されたクラスを利用していたオブジェクトを対象に，そのクラスがイミュータブ
ルであるか否かの調査を行った．調査の結果，イミュータブルクラスは HashMap では 14.8%，HashSet では 9.7%利用されていると明らかになった．また，過去バージョンではミュータブルクラスであったが，不整合のバグが発生したためにイミュータブルに変更された事例はまったく見つからなかった．
キーワード

イミュータビリティ，ハッシュ，Java

1. ま え が き

1 public final class Product {2

private final String name;// 品名

Java には複数のオブジェクトを格納するためのさまざまな

3

private final int price;// 価格

データ型が用意されている．その中には，HashMap や HashSet

4というデータ型が存在する．この 2 つのデータ型は，ハッシュ5値を用いてデータの格納を行う．例えば，HashSet では，要素6

this.name = name;となるオブジェクトのハッシュ値とハッシュ表を対応させるこ

7

this.price = price;とで，取り出したいデータの読み書きを行う [1]．このとき，要8}素に使用されたオブジェクトの内部状態を変更した場合，その9// 値を変更する関数が存在しない

オブジェクトのハッシュ値も同様に変化してしまう．つまり，

10 }HashMap のキーや HashSet の要素に用いられているオブジェク

public Product(String name, int price) {図 1 イミュータブルクラスの例

トの内部状態を変更すると，オブジェクト変更後のハッシュ値とハッシュ表に対応付けられているハッシュ値との間に不整合が更できない．このように，イミュータブルクラスはオブジェクト生じる [2]．このような HashMap のキーや HashSet の要素に使生成時からオブジェクトの内部状態が変更されることはないた

用されるオブジェクトの内部状態が変化を防ぐために，オブジェ

め，オブジェクトのハッシュ値が変更される心配はない．

クトの基となるクラスはイミュータブルにするべきといわれている [3] [4] [5] [6]．

しかしながら，実際のプロジェクトにおいてハッシュ値の不整合によるバグがどのくらい発生しているのか，またそのようなイミュータブルとは，オブジェクトの初期化後に値の変更が事象に対してイミュータブルクラスの実装による対処がどれく行えないことを指す [7]．図 1 は Java におけるイミュータブル

らい行われているのかは調査されてこなかった．現代の複雑なクラスの例である．このクラスは，与えられたフィールド変数すソフトウェア開発現場において [8]，コーディングに力を入れる

べてに final 修飾子が付けられており，一旦設定された値は変—1—

1 Calendar GetOneMonthLaterCalender(Calendar calendar){

HashMap のキーおよび HashSet の要素に焦点を当て，実装困難

2calendar.add(Calendar.MONTH,1);

な Java のイミュータブルクラスの必要性を調査することを目的

3

return calendar; //一ヶ月後の日付を返す

4 }

とする．

5 void CalenderMut(){

2. 2 調 査 対 象

6final Map<Calendar,Integer> map = new HashMap<>();

本研究の調査対象は GitHub 上に公開されている Java プロ

7

final Calendar calendar = Calendar.getInstance();

ジェクトのリポジトリである．数あるリポジトリの中で，イミュー

8map.put(calendar,1);

9

GetOneMonthLaterCalender(calendar); //内部状態が変化

10

map.get(calendar) //nullが出力される

11 }

タブルクラスの実装割合を客観的に調査する為に，Domains of（注 2）2,500 GitHub Repositories（以下，Domains）に掲載されている Java プロジェクト群と Apache（注 3）の 500 Stars 以上の Java図 2 HashMap のキーにミュータブルクラスを使用することによるバグ

プロジェクト群を調査候補に挙げた．この 2 つのプロジェクト群の中から，後述する調査方法で必要となる Jar ファイルが Mavenの例

Repository（注 4）にて配布されていること，クラスがイミュータブ
べき部分を明らかにすることは重要である．よって，困難といわルであるか解析するために使用したツールでエラーが発生しなれているイミュータブルクラスの実装 [9] の必要性を調べることかったこと，この 2 つの条件を満たすプロジェクトを対象としては効率的なソフトウェア開発に繋がる．

調査を行った．この条件に該当するプロジェクトは，Domains

本研究では，実際のプロジェクト 107 件を対象として HashMap

では 51 件，Apache では 56 件，計 107 件であった．

のキーおよび HashSet の要素に使用されているオブジェクトの2. 3 Mutability Detector

クラスのイミュータビリティを調べた．また，HashMap のキー

本研究の調査では，各々のクラスがイミュータブルである

および HashSet の要素のオブジェクトにイミュータブルクラス

かの判定に Mutability Detector（注 5）というツールを使用した．

を使用しなかったことによるバグが起きた事例が存在するのか

Mutability Detector は解析対象の各クラスについて以下の 4 つ調査を行った．

のうちいずれか 1 つを出力する．

•

COULD_NOT_ANALYSE•

NOT_IMMUTABLE

2. 1 ハッシュ値とミュータビリティ•

EFFECTIVELY_IMMUTABLE

java.util.Map の公式ドキュメントには，ミュータブルオブ•

IMMUTABLE

2. 準

備

ジェクトを Map のキーにつかうには細心の注意が必要であると

COULD_NOT_ANALYSE はそのクラスがなんらかの理由で解析で述べられている [2]．ミュータブルとは，オブジェクトの初期化きなかったことを表す．NOT_IMMUTABLE はそのクラスがミュータ後にもフィールドを変化させることができることを指す．そのブルであることを示す．EFFECTIVELY_IMMUTABLE と IMMUTABLE

ため，キーに使用されるオブジェクトに対し，equals メソッドの違いはマルチスレッド環境下でもイミュータブルかである．

による比較に影響を与えるような変更を行ったときに，ハッシュ

EFFECTIVELY_IMMUTABLE はシングルスレッドの場合のみイミ

値が変更されてしまいバリューとして登録されたオブジェクトュータブルであるのに対し，IMMUTABLE はマルチスレッドでもイを取り出せなくなる．

ミュータブルクラスとしてふるまう．この Mutability Detector

図 2 は ミ ュ ー タ ブ ル ク ラ ス を HashMap の キ ー に 使 用 しにおけるイミュータブルクラスの判定基準は Eﬀective Java [3]

た こ と に よ り ，正 し い 値 を 取 り 出 せ な く な っ た 例 で あ る ．

におけるイミュータブルクラスの実装規則に基づいている [11]．

java.util.Calender（注 1）はミュータブルクラスであり，図中

解析にはクラスファイルが必要となるため，Jar ファイルがのプログラムでも 1-4 行目メソッドでオブジェクトの内部状態

見つからなかったプロジェクトは調査から除外した．また，Jarが変化している．そのため，10 行目では正しい値を取り出せな

ファイルは見つかったものの，Mutability Detector のエラーにくなっている．仮に Calender クラスの中に add メソッドのよより解析できなかったプロジェクトも調査から除外した．

うなオブジェクトの内部状態を変化させるメソッドが無くす，

3. Research Question

フィールド変数に final 修飾子が付けるなどの処理を行ってい
れば，ハッシュ値の変化は起きず，10 行目で正しい値を取り出すことができたはずである．
以 上 の よ う に ，ミ ュ ー タ ブ ル ク ラ ス を HashMap の キ ー や本研究では，HashMap および HashSet に格納されるクラスがイミュータブルである必要性を調査する．この調査にあたり，以下に示す 2 つの Research Question（RQ）を設定した．

HashSet の要素に使用するとバグが起きる可能性があるため，オ
ブジェクトのクラスはイミュータブルにすることが推奨されている．しかしながら，既存研究 [10] では Java におけるイミュー
タブルクラスの実装は困難であるとされている．本研究では，（注 2）：https://docs.google.com/spreadsheets/d/1oOIyVTsuJU0aQKgV8H

5jWQKzLovoycf9ZjtajqEU8dc（注 3）：https://github.com/apache（注 1）：https://docs.oracle.com/en/java/javase/17/docs/api/java.ba（注 4）：https://mvnrepository.com

se/java/util/Calendar.html（注 5）：https://github.com/MutabilityDetector/MutabilityDetector—2—Map<○○, □□> = …
Map<△△, ◇◇> = …
HashMap<××, ☆☆> = …
…
ソースコードファイル

プロジェクト

1. AST解析によりHashMapまたはMapの宣⾔箇所を抽出…○○ is NOT_IMMUTABLE…□□ is IMMUTABLE…△△ is COULD_NOT_ANALISIS…
Jarファイル…○○ is NOT_IMMUTABLE…×× is IMMUTABLE…
3. HashMapまたはMapに使われたクラスがイミュータブ
ルかを出⼒

2. Mutability Detectorにより各クラスがイミュータブルか判定
図 3 RQ1 の調査方法

RQ1: HashMap のキーおよび HashSet の要素に使用されるオ
ブジェクトのクラスがイミュータブルである割合はどの程度か

4. 調 査 方 法

実プロジェクトにおいて HashMap のキーと HashSet の要素

RQ1 に回答するために，2. 2 で挙げた実プロジェクト 107 件に用いられているクラスのうちイミュータブルクラスである割を対象に解析を行い，調査対象のイミュータブルクラスの実装割合を算出する．この割合と既存研究 [12] で算出されているプロ合を調べる．調査対象のクラスは，プロジェクト作成者がクラス

ジェクト全体のクラスのうちイミュータブルクラスである割合

をミュータブルからイミュータブルに変更可能である，プロジェとを比較する．HashMap のキーや HashSet の要素のオブジェク

クト内で定義されたクラスに限定する．また，RQ2 に回答する

トのクラスがミュータブルであることに起因するバグが頻発すために RQ1 の調査中に検出されたイミュータブルクラスについるのであれば，そのバグに対応するために当該クラスがイミューて過去にミュータブルクラスであったかを調べ，そのクラスがタブルに修正されると著者らは考えた．そのため，プロジェク

HashMap のキーあるいは HashSet の要素であることに起因する

ト全体におけるイミュータブルクラスの割合に比べ，HashMap

バグによって変更されたのかを調査する．

のキーや HashSet の要素のオブジェクトのクラスにおけるイ

4. 1 RQ1

ミュータブルクラスの割合が大きいのであれば，HashMap のキー

説明を簡素にするため，HashMap のキーについて解析する手および HashSet の要素に使用されるオブジェクトのクラスをイ順に絞って説明する．調査の流れを図 3 に示す．調査にはプロ

ミュータブルクラスにする必要性は高いと結論付けられる．反対

ジェクトのソースコードファイルと Jar ファイルを用い，以下のに，プロジェクト全体におけるイミュータブルクラスの割合に比順で行う．

べ，HashMap のキーや HashSet の要素のオブジェクトのクラス
におけるイミュータブルクラスの割合に大きな変化が無ければ，

1. HashMap または Map のキーに使用されたクラスを抽出する

HashMap のキーや HashSet の要素のオブジェクトのクラスをイ
ミュータブルにする理由は特別存在しないと結論付けられる．

2. プロジェクト内の各クラスのイミュータビリティを判定する

RQ2: HashMap のキーおよび HashSet の要素に使用されるオ
ブジェクトのクラスがミュータブルであることに起因するバ

3. 2. の結果から 1. で抜き出したクラスの解析結果を抽出する

グは存在するのか

各手順について以下で詳しく説明する．

HashMap のキーや HashSet の要素のオブジェクトのクラスが4. 1. 1 HashMap または Map のキーに使用されたクラスを抽

ミュータブルであることに起因するバグが発見できれば，HashMap

出するのキーおよび HashSet の要素に使用されるオブジェクトのクラ

プロジェクトのソースコードに対して AST 解析を行い，スをイミュータブルに変更すべき根拠となりえる．反対にそのHashMap もしくは Map が宣言されている箇所を抽出する．このようなバグの事例が見つからなければ，HashMap のキーおよび

とき，プロジェクト内で定義されたクラスが調査対象のため，

HashSet の要素に使用されるオブジェクトのクラスをイミュー

HashMap のキーに使用されている型が基本データ型のラッパー

タブルにすべきである根拠は乏しくなるため，HashMap のキークラス（注 6）あるいは String 型である場合，抽出の処理対象とはなおよび HashSet の要素に使用されるオブジェクトのクラスをイらない．

ミュータブルにする必要性は低くなると考えられる．

例えば，図 4 のコードでは，1 行目および 2 行目は HashMap もし
くは Map が宣言されていないため無視する．3 行目は integerMap（注 6）：Boolean, Character, Byte, Short, Integer, Long, Float, Double—3—2. 1. のクラスがイミュータブルに変化した原因を調査する

1 int b = 1; //無視
2 System.out.println(b); //無視
3 Map<Integer, String> integerMap = new HashMap<>(); //無視
4 Map<Obj, String> objMap = new HashMap<>(); //Objを抽出

各手順について以下で詳しく説明する．

4. 2. 1 過去にミュータブルであったクラスを見つける
まずは，バグ修正を行った可能性のあるクラスを見つけ出す

図 4 AST 解析で抽出されるコード（HashMap の場合）

ため，ミュータブルからイミュータブルに変更されたことのあるクラスを探す．その方法として，RQ1 でイミュータブルクラス

が HashMap のデータ型として宣言されているものの，キーとしと出力されたクラスを対象とし，そのクラスが解析可能な最も古て使われているクラスがが基本データ型のラッパークラスであい Jar ファイルについてもイミュータブルクラスであるかどう

る Integer であるため無視する．最後に，4 行目は HashMap がかの解析を行い，過去にミュータブルであったクラスが存在する

宣言されており，キーに使われているクラスが基本データ型のかを調べる．

ラッパークラスや String 型のクラスではない objMap であるた
め，キーとして使われているデータ型の Obj を抽出する．
なお，エラーにより解析できなかった Java ファイルについて解析に用いるのは基本的にそのクラスが含まれるプロジェク
トの最も古い Jar ファイルであるが，以下の条件に当てはまる場
合は次に古い Jar ファイルへと繰り上がっていく．

は，ファイル内で “Map” あるいは “HashMap” という文字列が存•在するかどうかを出力する．存在する場合，該当のファイルのとき

Map または HashMap のデータ型が使われている箇所について目•

解析対象のクラスがまだ未実装であったとき

視で確認し，キーに使われているオブジェクトのクラスがプロ•

解析対象のクラスで COULD_NOT_ANALYSE が出力された

ジェクト内で定義されたクラスである場合は該当のキーの抽出

とき

を行う．

Mutability Detector のエラーにより解析できなかった

つ ま り ，解 析 対 象 の ク ラ ス に つ い て ，NOT_IMMUTABLE，

4. 1. 2 HashMap または Map のキーに使用されたクラスを抽出する

2. 3 で説明した Mutability Detector を使用し，プロジェクトの Jar ファイル内を解析して各クラスがイミュータブルであるかを出力する．

4. 1. 3 4.1.2 の結果から 4.1.1 で抜き出したクラスの解析結果を抽出する

EFFECTIVELY_IMMUTABLE，IMMUTABLE のいずれかが出力されるまで Jar ファイルのバージョンを徐々に上げていく．

4. 2. 2 4.2.1 のクラスがイミュータブルに変化した原因を調査する
次に，ミュータブルからイミュータブルに変更されたクラス
について，どのような理由でミュータブルクラスからイミュータ
ブルクラスに変更されたのかを調べ，ハッシュ値に起因するバグ

イミュータビリティの出力から HashMap または Map のキーにの事例が存在するかを調査する．当該クラスに対して，Jar ファ

使われているクラスの出力のみを表示させ，キーに使用されていイルが提供されている各バージョンでも Mutability Detector をるクラスイミュータビリティの割合を算出する．イミュータビ

用いてイミュータブルクラスであるかの判定を行い，ミュータブ

リティの割合の算出対象とするクラスは以下の例外を除いた全

ルからイミュータブルに変更されたバージョンを特定する．そてのクラスである．

して，当該プロジェクトのリポジトリのコミット履歴をたどり，•

COULD_NOT_ANALYSE と出力されたときミュータブルクラスと最後に出力されたバージョンからイミュー•

同名のクラスが複数出力されたときタブルクラスと最初に出力されたバージョンの間でどのような変•当該プロジェクト内で定義されていないクラスである場合

更が行われたのかを確認する．変更された箇所やコミットメッ

1 つ目の COULD_NOT_ANALYSE と出力された場合は，イミュー

セージを確認し，変更が HashMap のキーや HashSet の要素に使

タブルクラスであるか判別できないため，プロジェクト内で定義されたクラスであっても無視する．2 つ目の同名クラスが複用したことに起因するバグであるかを調査する．

数出力された場合は，どのクラスが HashMap のキーに使われ5. 調 査 結 果

たクラスか判別できないため，割合の算出には用いない．3 つ

5. 1 RQ1

目の当該プロジェクト内で定義されていないクラスは，例えばHashMap の調査結果を表 1 に，HashSet の調査結果を表 2

java.io.File などの Java の API で提供されているクラスなどに示す．HashMap に使用されたオブジェクトのクラスのうち，が該当する．このような自身のプロジェクト内で定義されていMutability Detector で解析できたクラスは 411 件あり，そのうないクラスをキーとして使用している場合，プロジェクト作成者

ちイミュータブルクラスは 61 件であった．HashSet に使用されによってイミュータブルクラスに変更することができないため，たオブジェクトのクラスのうち，Mutability Detector で解析で割合の算出には用いない．

きたクラスは 548 件あり，そのうちイミュータブルクラスは 53

HashSet についても，HashSet と Set の要素を対象として
4.1.1 から 4.1.3 の作業を行なう．

件であった．この結果から，プロジェクト内で定義されたクラス
において，HashMap のキーに使用されたクラスがイミュータブ

4. 2 RQ2

ルクラスであった割合は 14.8%，HashSet の要素に使用された

RQ2 の調査について，以下の手順で行う．

クラスがイミュータブルクラスであった割合は 9.7%であった．

1. 過去にミュータブルであったクラスを見つける

以上に調査により判明した，HashMap のキーに使われたクラ—4—

スにおけるイミュータブルクラスの割合および HashSet の要素に使われたクラスにおけるイミュータブルクラスの割合をプロ
ジェクト全体におけるイミュータブルクラスの割合と比較する．

- public final class BarcodeFormat {- // No, we can't use an enum here. J2ME doesn't support it.
+ public enum BarcodeFormat {既存研究 [12] の調査では，Apache のライブラリにおいては 485

図 5 zxing の BarcodeFormat の変更（一部抜粋）

件のクラスのうち 69 件のイミュータブルクラスを検出していた．
よって，Apache のライブラリにおけるイミュータブルクラスの実装率は 14.2%である．この割合と今回の調査結果を比較する

private final String name;private final String type;- private final Optional<SimpleDomain> domain;とほとんど差がないことが分かる．この事実から，HashMap の

図 6 presto の Column の変更（一部抜粋）

キーや HashSet の要素のオブジェクトのクラスであっても，積極的にイミュータブルクラスにしているわけではないことが分- public class CHPX extends BytePropertyNode+ public final class CHPX extends BytePropertyNodeかる．

図 7 poi の CHPX の変更

RQ1 への回答：と HashMap および HashSet に用いられるイ
ミュータブルクラスの割合はそれぞれ 14.8%，9.7%であり，素の双方に使用されたイミュータブルクラス 14 件，計 101 件のプロジェクト全体のイミュータブルクラスの割合とほとんど

イミュータブルクラスを調査した．

差はない．

101 件のうち，過去にミュータブルだったクラスは，ZXing（注 8）のBarcodeFormat と ResultMetaDataType，Presto（注 9）の Column，

5. 2 RQ2
HashMap のキーや HashSet の要素のオブジェクトのクラスがミュータブルであることに起因するバグの事例を調べるため，まずRQ1 で検出されたイミュータブルクラスについて，過去にミュー
タブルであったクラスを調べた．なお，Apache Lucene（注 7）に関しては過去バージョンの Jar ファイルを Mutability Detector で解析できなかったため，該当プロジェクトの HashMap のキーに使用された 2 件のイミュータブルクラスについては調査できなかった．この 2 件を除いて，HashMap のキーのみに使用された
イミュータブルクラス 48 件，HashSet の要素のみに使用された
イミュータブルクラス 39 件，HashMap のキーと HashSet の要

Apache POI（注 10）の CHPX の 4 件であった．
次に，当該クラスがミュータブルからイミュータブルに変更
された時期を調査する．各プロジェクトについて，バージョン
ごとにイミュータブルクラスであるかの解析を行ったところ，

ZXing の BarcodeFormat と ResultMetaDataType は ver1.7 から ver2.0 にて，Presto の Column は ver0.119 から ver0.120 にて，Apache POI の CHPX は ver3.5-beta5 から ver3.5-beta6 にて，当該クラスがミュータブルからイミュータブルに変更されていた．
最後に，当該クラスが，ミュータブルからイミュータブルに変更された理由を調査する．各クラスがイミュータブルに変更されたバージョン間のコミット履歴を辿った．ZXing について，イ

表 3 イミュータブルクラスの割合の比較
割合

ミュータブルクラスに変更されたバージョン間で BarcodeFormat[既存研究]Apache プロジェクト全体 14.2%

は 2 回，ResultMetaDataType は 1 回変更がなされていた．そプロジェクト名

Apache合計

HashMap

15.2%の中でイミュータブルクラスに変更された要因は，図 5 のよう

HashSet8.1%に列挙型のクラスに変更したためであると考えられる．Presto

HashMap

14.8%

HashSet9.7%（注 8）：https://github.com/zxing/zxing（注 9）：https://github.com/prestodb/presto（注 10）：https://github.com/apache/poi（注 7）：https://github.com/apache/lucene

表1

HashMap のキーの調査結果
Domains Apache

Map または HashMap を検出した数（基本データ型，String 型を除く）

合計

2,795

5,700

8,495

検出されたキーのオブジェクトの種類

628

1,124

1,752

プロジェクト内で定義され，ツールにより解析できたクラスの数

135

276

411

イミュータブルであったクラス

19

42

61

イミュータブルクラスの割合

14.1%
表2

15.2% 14.8%

HashSet の要素の調査結果
Domains Apache

Set または HashSet を検出した数（基本データ型，String 型を除く）

合計

2,364

4,920 7,284検出された要素のオブジェクトの種類

786

1,355 2,141

プロジェクト内で定義され，ツールにより解析できたクラスの数

189

359

548

イミュータブルであったクラス

24

29

53

12.7%

8.1%

9.7%

イミュータブルクラスの割合—5—

の Column はイミュータブルクラスに変更されたバージョン間で1 回だけ変更されていた．イミュータブルクラスに変更された要

8. あ と が き

因は，図 6 の通り，クラス内部のミュータブルフィールドを削除

本研究では，HashMap のキーや HashSet の要素に使用されるしたためであると考えられる．このフィールドを削除した理由

オブジェクトの基となるクラスという側面から，イミュータブル

は，そのフィールドの基クラスを削除したためであり，HashSet

クラスを実装する必要性を調査した．調査の結果，HashMap のの要素に Column を使用していることは関係ない．Apache POI

キーや HashSet の要素のオブジェクトのクラスをイミュータブの CHPX はイミュータブルクラスに変更されたバージョン間で 1ルとする必要性は低いことが分かった．

回だけ変更されていた．イミュータブルクラスに変更された要今後の課題として，別の側面におけるイミュータブルクラス

因は，クラスに final 修飾子を付けたことでサブクラス化できを実装する必要性の調査が挙げられる．例えば，イミュータブル

なくなったためであると考えられる．

クラスは並列プログラミングにおいて同期を必要としないため，

この調査結果から，HashMap および HashSet にミュータブルク

排他制御を最小限に抑え実行速度を向上させることができるとラスを使用したことに起因するバグの実例は見つからなかった．

もいわれている．このようなイミュータブルクラスが持つ様々な利点についてそれぞれ検証を行うことで，イミュータブルクラ

RQ2 への回答：今回の調査において，HashMap および HashSetにミュータブルクラスを用いたことに起因するバグの実例は全く見つからなかった．

スの総合的な価値を調べることに繋がると考える．
謝辞

本研究は JSPS 科研費（JP20H04166，JP21K18302，

JP21K11820，JP21H04877，JP22H03567，JP22K11985）の助成を得て行われた．

6. 考察

RQ1 の調査結果から HashMap および HashSet に用いられるオブジェクトのクラスにおけるイミュータブルクラスの割合はプロジェクト全体のイミュータブルクラスの割合と差がないことが判明した．この結果から，実際のプロジェクトでは，クラスがミュータブルであっても問題なく運用されていると結論付けることができ，HashMap および HashSet に用いられるオブジェ
クトのクラスをイミュータブルにする必要性は低いといえる．
また，RQ2 の調査結果においても 100 件以上のイミュータ
ブルクラスを対象にした調査にもかかわらず，HashMap および

HashSet にミュータブルクラスを使用したことに起因するバグの実例を発見することはできなかった．この結果から，HashMapのキーや HashSet の要素のオブジェクトのクラスがミュータブ
ルであることによるバグが起こる事例はめったにないと考えられる．
以上の調査より，HashMap のキーおよび HashSet の要素に用いられるオブジェクトのクラスをイミュータブルにする必要性は低いと結論付けられる．

7. 妥当性の脅威
RQ1 の調査では，キーや要素に使用されているオブジェクトのクラスのうち，イミュータブルであるか判別できたプロジェク
ト内クラスの割合は HashMap では 23.5%，HashSet では 25.6%である．そのため，今回のプロジェクトを網羅的に解析できれば，イミュータブルクラスの割合が変動したり，バグの実例が見つかる可能性がある．

RQ2 の調査では，プロジェクトのすべての Jar ファイルに対してイミュータブルクラスであるかの判定を行ったわけではな
い．そのため，イミュータブルクラスが途中でミュータブルクラ
スに変化し，再度イミュータブルクラスに変更された事例が存在する可能性がある．

文

献[1] Oracle, “HashSet (Java SE 17 & JDK 17),” accessed 202206-12. https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/HashSet.html.
[2] Oracle, “Map (Java SE 17 & JDK 17),” accessed 2022-06-12.
https://docs.oracle.com/en/java/javase/17/docs/api/j
ava.base/java/util/Map.html.
[3] J. Bloch, Eﬀective java, Addison-Wesley Professional, 2008.
[4] stackoverﬂow, “Immutable objects and hashmap keys
[closed],” accessed 2022-06-12. https://stackoverflow.
com/questions/20212440.
[5] Quora, “Why should the HashMap key be immutable in
Java?,” accessed 2022-06-12. https://www.quora.com/Wh
y-should-the-HashMap-key-be-immutable-in-Java.
[6] stackoverﬂow, “Why is it preferred to use immutable objects as elements of a Set?,” accessed 2022-06-12. https://stackoverflow.com/questions/37335407.
[7] A. Potanin, J. Östlund, Y. Zibin, and M.D. Ernst, “Immutability,” pp.233–269, Springer Berlin Heidelberg, Berlin,
Heidelberg, 2013. https://doi.org/10.1007/978-3-642-369469_9[8] K. Wnuk, B. Regnell, and B. Berenbach, “Scaling up requirements engineering – exploring the challenges of increasing
size and complexity in market-driven software development,”
Requirements Engineering: Foundation for Software Quality,eds. by D. Berry and X. Franch, pp.54–59, Springer Berlin
Heidelberg, Berlin, Heidelberg, 2011.
[9] M. Coblenz, W. Nelson, J. Aldrich, B. Myers, and J. Sunshine, “Glacier: Transitive class immutability for java,”
In Proc. International Conference on Software Engineering(ICSE), pp.496–506, 2017.
[10] M. Coblenz, J. Sunshine, J. Aldrich, B. Myers, S. Weber,and F. Shull, “Exploring language support for immutability,”
In Proc. International Conference on Software Engineering(ICSE), pp.736–747, 2016.
[11] MUTABILITY DETECTOR BLOG, “An Introduction To
Mutability Detector (Part 1 of n),” accessed 2022-06-12.
http://mutability- detector.blogspot.com/2010/07/i
ntroduction-to-mutability-detector.html.
[12] T. Roth, D. Helm, M. Reif, and M. Mezini, “Ciﬁ: Versatile analysis of class and ﬁeld immutability,” In Proc. International Conference on Automated Software Engineering(ASE), pp.979–990, 2021.

—6—