3. AbstractList を継承して実装されている p pu ub bl li ic c c cl la as ss s A Ar rr ra ay yL Li is st t< <E E> > e ex xt te en nd ds s A Ab bs st tr ra ac ct tL Li is st t< <E E> > i im mp pl le em me en nt ts s L Li is st t< <E E> >, , R Ra an nd do om mA Ac cc ce es ss s, , C Cl lo on ne ea ab bl le e, , S Se er ri ia al li iz za ab bl le e
ur re eC Ca ap pa ac ci it ty y( (i in nt t) ), t tr ri im mT To oS Si iz ze e( () ) のみが固有 • ArrayList を知るために ◦ List インタフェースのことを知る必要がある ◦ さらに、その親インタフェースも知る必要がある
element) 取得 E get(int index) 削除 E remove(int index) 検索 int indexOf(Object o) 部分取得 List<E> subList(int fromIndex, int toIndex) ソート void sort(Comparator<? super E> c) • インデックスを指定しての操作が特徴的
int hashCode() • List インタフェースとして e eq qu ua al ls s と h ha as sh hC Co od de e が定義さ れている ◦ 実装に関わらず、リスト内の要素がすべて同じなら e eq qu ua al ls s が t tr ru ue e で、h ha as sh hC Co od de e の値が等しくなる
を取得できる ◦ View に変更した内容は、元のコレクションに反映される ◦ この View は、for ループできる f fo or r ( (v va ar r e e : : l li is st t. .r re ev ve er rs se ed d( () )) ) { { S Sy ys st te em m. .o ou ut t. .p pr ri in nt tl ln n( (e e) ); ; } }
追加 boolean addAll(Collection<? extends E> c) 削除 E remove(Object element) 検索 boolean contains(Object element) • List インタフェースと異なる a ad dd d( (E E) ) がある ◦ インデックスの指定ができない ◦ 戻り値がある(Set でコレクションが変更されなかった場 合は f fa al ls se e になる。List の場合は常に t tr ru ue e になる)
Colleciton インタフェースにあったメソッド ◦ Java 5 で独⽴したインタフェースになった • この他に、Java 8 でデフォルトメソッドが追加された ◦ v vo oi id d f fo or rE Ea ac ch h( (C Co on ns su um me er r< <? ? s su up pe er r T T> > a ac ct ti io on n) ) ◦ S Sp pl li it te er ra at to or r< <T T> > s sp pl li it te er ra at to or r( () )
複数のマーカーインタフェース(後述)がある 3. AbstractList を継承して実装されている p pu ub bl li ic c c cl la as ss s A Ar rr ra ay yL Li is st t< <E E> > e ex xt te en nd ds s A Ab bs st tr ra ac ct tL Li is st t< <E E> > i im mp pl le em me en nt ts s L Li is st t< <E E> >, , R Ra an nd do om mA Ac cc ce es ss s, , C Cl lo on ne ea ab bl le e, , S Se er ri ia al li iz za ab bl le e
c c cl la as ss s A Ar rr ra ay yL Li is st t< <E E> > e ex xt te en nd ds s A Ab bs st tr ra ac ct tL Li is st t< <E E> > i im mp pl le em me en nt ts s L Li is st t< <E E> >, , R Ra an nd do om mA Ac cc ce es ss s, , C Cl lo on ne ea ab bl le e, , S Se er ri ia al li iz za ab bl le e メソッドやフィールドが⼀切定義されていないインタフェース。 クラスの特徴を表すために⽤いる。 マーカーインタフェース
le ec ct ti io on ns s. .b bi in na ar ry yS Se ea ar rc ch h( () )など)で は、このインタフェースの有無によって使⽤するアルゴ リズムを変えている • Cloneable ◦ c cl lo on ne e( () ) メソッドに対応 • Serializable ◦ シリアライズ可能
ic c c cl la as ss s A Ar rr ra ay yL Li is st t< <E E> > e ex xt te en nd ds s A Ab bs st tr ra ac ct tL Li is st t< <E E> > i im mp pl le em me en nt ts s L Li is st t< <E E> >, , R Ra an nd do om mA Ac cc ce es ss s, , C Cl lo on ne ea ab bl le e, , S Se er ri ia al li iz za ab bl le e
l li is st t = = n ne ew w A Ar rr ra ay yL Li is st t< <S St tr ri in ng g> >( (. .. .. .) ); ; v va ar r s sy yn nc cL Li is st t = = C Co ol ll le ec ct ti io on ns s. .s sy yn nc ch hr ro on ni iz ze ed dL Li is st t( (l li is st t) ); ; • または CopyOnWriteArrayList(スレッドセーフな ArrayList 実装)を使う
si ie en nt t O Ob bj je ec ct t[ [] ] e el le em me en nt tD Da at ta a; ; ↑ ↑ シリアル化の対象外にする修飾子 / // / 現在使用中のサイズ p pr ri iv va at te e i in nt t s si iz ze e; ; ( (A Ab bs st tr ra ac ct tL Li is st t) ) / // / 構造が変更された回数(ループ中の変更を検出するための変数) p pr ro ot te ec ct te ed d t tr ra an ns si ie en nt t i in nt t m mo od dC Co ou un nt t = = 0 0; ;
st t( () ) ◦ 初期容量10で空のリストを作成 • A Ar rr ra ay yL Li is st t( (i in nt t i in ni it ti ia al lC Ca ap pa ac ci it ty y) ) ◦ 指定された初期容量で空のリストを作成 • A Ar rr ra ay yL Li is st t( (C Co ol ll le ec ct ti io on n< <? ? e ex xt te en nd ds s E E> > c c) ) ◦ コピーコンストラクタ ◦ 指定されたコレクションをコピーしたリストを作成
c A Ar rr ra ay yL Li is st t( () ) { { t th hi is s( (1 10 0) ); ; } } • 初期容量を指定するコンストラクタを呼び出す ◦ t th hi is s. .e el le em me en nt tD Da at ta a = = n ne ew w O Ob bj je ec ct t[ [1 10 0] ] となる Java 7 Update 40 以降では、次ページの遅延初期化する実装に変更 この実装は Java 7 Update 25 まで
e s st ta at ti ic c f fi in na al l O Ob bj je ec ct t[ [] ] D DE EF FA AU UL LT TC CA AP PA AC CI IT TY Y_ _E EM MP PT TY Y_ _E EL LE EM ME EN NT TD DA AT TA A = = { {} }; ; p pu ub bl li ic c A Ar rr ra ay yL Li is st t( () ) { { t th hi is s. .e el le em me en nt tD Da at ta a = =D DE EF FA AU UL LT TC CA AP PA AC CI IT TY Y_ _E EM MP PT TY Y_ _E EL LE EM ME EN NT TD DA AT TA A; ; } } • 配列を作成せず、Singleton な空配列を使う ◦ 最初に a ad dd d メソッドが呼ばれた際に作成(遅延初期化) ◦ ArrayList を作っても要素の追加が⾏われないことが多々 あるため(JDK-7143928)
e s st ta at ti ic c f fi in na al l O Ob bj je ec ct t[ [] ] E EM MP PT TY Y_ _E EL LE EM ME EN NT TD DA AT TA A = = { {} }; ; p pu ub bl li ic c A Ar rr ra ay yL Li is st t( (i in nt t i in ni it ti ia al lC Ca ap pa ac ci it ty y) ) { { i if f ( (i in ni it ti ia al lC Ca ap pa ac ci it ty y > > 0 0) ) { { t th hi is s. .e el le em me en nt tD Da at ta a = = n ne ew w O Ob bj je ec ct t[ [i in ni it ti ia al lC Ca ap pa ac ci it ty y] ]; ; } } e el ls se e i if f ( (i in ni it ti ia al lC Ca ap pa ac ci it ty y = == = 0 0) ) { { t th hi is s. .e el le em me en nt tD Da at ta a = = E EM MP PT TY Y_ _E EL LE EM ME EN NT TD DA AT TA A; ; } } e el ls se e { { t th hr ro ow w n ne ew w I Il ll le eg ga al lA Ar rg gu um me en nt tE Ex xc ce ep pt ti io on n( (… …s sn ni ip p… …) ); ; } } } }
lC Ca ap pa ac ci it ty y が … 1. > 0 の場合 ◦ i in ni it ti ia al lC Ca ap pa ac ci it ty y の容量の配列を作成し、 t th hi is s. .e el le em me en nt tD Da at ta a に代⼊ 2. == 0 の場合 ◦ Singleton の空配列 E EM MP PT TY Y_ _E EL LE EM ME EN NT TD DA AT TA A を、 t th hi is s. .e el le em me en nt tD Da at ta a に代⼊ 3. < 0 の場合 ◦ I Il ll le eg ga al lA Ar rg gu um me en nt tE Ex xc ce ep pt ti io on n をスロー
ic c A Ar rr ra ay yL Li is st t( (C Co ol ll le ec ct ti io on n< <? ? e ex xt te en nd ds s E E> > c c) ) { { O Ob bj je ec ct t[ [] ] a a = = c c. .t to oA Ar rr ra ay y( () ); ; i if f ( (( (t th hi is s. .s si iz ze e = = a a. .l le en ng gt th h) ) ! != = 0 0) ) { { i if f ( (c c. .g ge et tC Cl la as ss s( () ) = == = A Ar rr ra ay yL Li is st t. .c cl la as ss s) ) { { t th hi is s. .e el le em me en nt tD Da at ta a = = a a; ; } } e el ls se e { { t th hi is s. .e el le em me en nt tD Da at ta a = = A Ar rr ra ay ys s. .c co op py yO Of f( (a a, , s si iz ze e, , O Ob bj je ec ct t[ [] ]. .c cl la as ss s) ); ; } } } } e el ls se e { { t th hi is s. .e el le em me en nt tD Da at ta a = = E EM MP PT TY Y_ _E EL LE EM ME EN NT TD DA AT TA A; ; } }
Ar rr ra ay y( () ) によりコレクションの配列を取得 2. 取得した配列の⻑さを t th hi is s. .s si iz ze e に代⼊ 3. t th hi is s. .s si iz ze e > 0 の場合 ◦ (次ページに記載) 4. t th hi is s. .s si iz ze e == 0 の場合 ◦ Singleton の空配列 E EM MP PT TY Y_ _E EL LE EM ME EN NT TD DA AT TA A を、 t th hi is s. .e el le em me en nt tD Da at ta a に代⼊
si iz ze e > 0 の場合 1. 引数 c c が ArrayList の場合 ◦ 取得した配列 a a をt th hi is s. .e el le em me en nt tD Da at ta a に代⼊ 2. 引数 c c が ArrayList 以外の場合 ◦ 取得した配列 a a の中⾝を新しい O Ob bj je ec ct t[ [] ] にコピーして から、t th hi is s. .e el le em me en nt tD Da at ta a に代⼊(防御的コピー) → なぜ防御的コピーが必要︖ → なぜ ArrayList の場合は不要︖
ra ay y( () ) の戻り値の型は O Ob bj je ec ct t[ [] ] → 任意の型の配列(S St tr ri in ng g[ [] ]など)を返すことができて しまう(配列の共変性) • もし O Ob bj je ec ct t[ [] ] 以外だったら︖ ◦ そのまま t th hi is s. .e el le em me en nt tD Da at ta a に使ってしまうと、リス トの変更時に ArrayStoreException のリスク︕ これを避けるため、新しく O Ob bj je ec ct t[ [] ] を作りコピーしている
c E Ev vi il lC Co ol ll le ec ct ti io on n i im mp pl le em me en nt ts s C Co ol ll le ec ct ti io on n< <E E> > { { p pu ub bl li ic c O Ob bj je ec ct t[ [] ] e el le em me en nt ts s = = n ne ew w O Ob bj je ec ct t[ [1 10 0] ]; ; p pu ub bl li ic c O Ob bj je ec ct t[ [] ] t to oA Ar rr ra ay y( () ) { { r re et tu ur rn n e el le em me en nt ts s; ; } } } } • この場合、EvilCollection の e el le em me en nt ts s を操作することで、 ArrayList の外部から変更ができてしまう︕ ◦ コンストラクタ内でコピーすることで、できなくする
ra ay y( () ) の場合 ◦ 新しい O Ob bj je ec ct t[ [] ] にコピーしたものを返しているから、 そのまま使って⼤丈夫 p pu ub bl li ic c O Ob bj je ec ct t[ [] ] t to oA Ar rr ra ay y( () ) { { r re et tu ur rn n A Ar rr ra ay ys s. .c co op py yO Of f( (e el le em me en nt tD Da at ta a, , s si iz ze e) ); ; } }
c b bo oo ol le ea an n a ad dd d( (E E e e) ) { { m mo od dC Co ou un nt t+ ++ +; ; a ad dd d( (e e, , e el le em me en nt tD Da at ta a, , s si iz ze e) ); ; r re et tu ur rn n t tr ru ue e; ; } } p pr ri iv va at te e v vo oi id d a ad dd d( (E E e e, , O Ob bj je ec ct t[ [] ] e el le em me en nt tD Da at ta a, , i in nt t s s) ) { { i if f ( (s s = == = e el le em me en nt tD Da at ta a. .l le en ng gt th h) ) e el le em me en nt tD Da at ta a = = g gr ro ow w( (s si iz ze e + + 1 1) ); ; e el le em me en nt tD Da at ta a[ [s s] ] = = e e; ; t th hi is s. .s si iz ze e = = s s + + 1 1; ; } }
mo od dC Co ou un nt t を + 1 2. 空きがない場合 ◦ g gr ro ow w( (s si iz ze e + + 1 1) ) で新しい容量の配列を作る(後述) 3. 最後尾にオブジェクトを追加 4. t th hi is s. .s si iz ze e を + 1 5. t tr ru ue e を return
li ic c v vo oi id d a ad dd d( (i in nt t i in nd de ex x, , E E e el le em me en nt t) ) { { r ra an ng ge eC Ch he ec ck kF Fo or rA Ad dd d( (i in nd de ex x) ); ; m mo od dC Co ou un nt t+ ++ +; ; f fi in na al l i in nt t s s; ; O Ob bj je ec ct t[ [] ] e el le em me en nt tD Da at ta a = = t th hi is s. .e el le em me en nt tD Da at ta a; ; i if f ( (( (s s = = s si iz ze e) ) = == = e el le em me en nt tD Da at ta a. .l le en ng gt th h) ) e el le em me en nt tD Da at ta a = = g gr ro ow w( (s s + + 1 1) ); ; S Sy ys st te em m. .a ar rr ra ay yc co op py y( (e el le em me en nt tD Da at ta a, , i in nd de ex x, , e el le em me en nt tD Da at ta a, , i in nd de ex x + + 1 1, , s s - - i in nd de ex x) ); ; e el le em me en nt tD Da at ta a[ [i in nd de ex x] ] = = e el le em me en nt t; ; s si iz ze e = = s s + + 1 1; ; } }
ex x < < 0 0 または i in nd de ex x > >= = s si iz ze e)の場合 ◦ IndexOutOfBoundsException をスロー 2. t th hi is s. .m mo od dC Co ou un nt t を + 1 3. 空きがない場合 ◦ g gr ro ow w( (s si iz ze e + + 1 1) ) で新しい容量の配列を作る(後述) 4. 指定されたインデックス + 1 以降を、⼀つ後ろにコピー 5. 指定されたインデックスにオブジェクトを追加 6. t th hi is s. .s si iz ze e を + 1
e O Ob bj je ec ct t[ [] ] g gr ro ow w( (i in nt t m mi in nC Ca ap pa ac ci it ty y) ) { { i in nt t o ol ld dC Ca ap pa ac ci it ty y = = e el le em me en nt tD Da at ta a. .l le en ng gt th h; ; i if f ( (o ol ld dC Ca ap pa ac ci it ty y > > 0 0 | || | e el le em me en nt tD Da at ta a ! != = D DE EF FA AU UL LT TC CA AP PA AC CI IT TY Y_ _E EM MP PT TY Y_ _E EL LE EM ME EN NT TD DA AT TA A) ) { { / // / 省略:必要な容量を計算 r re et tu ur rn n e el le em me en nt tD Da at ta a = = A Ar rr ra ay ys s. .c co op py yO Of f( (e el le em me en nt tD Da at ta a, , n ne ew wC Ca ap pa ac ci it ty y) ); ; } } e el ls se e { { r re et tu ur rn n e el le em me en nt tD Da at ta a = = n ne ew w O Ob bj je ec ct t[ [M Ma at th h. .m ma ax x( (D DE EF FA AU UL LT T_ _C CA AP PA AC CI IT TY Y, , m mi in nC Ca ap pa ac ci it ty y) )] ]; ; } }
Ca ap pa ac ci it ty y か 現在の容量の 1.5倍の⼤きい⽅を 容量とする(例外あり、最後に解説) 2. 新しい配列に、現在の配列の内容をコピー 3. t th hi is s. .e el le em me en nt tD Da at ta a を新しい配列に差し替え 最低限必要な分ではなく、まとめて⼤きくする ポイント2
e en ns su ur re eC Ca ap pa ac ci it ty y( (i in nt t m mi in nC Ca ap pa ac ci it ty y) ) を使う ◦ ⼤量の要素を追加する前に使うと、配列のコピーを減ら せる • 容量は⾃動的に縮⼩しない ◦ 縮⼩するには、明⽰的に t tr ri im mT To oS Si iz ze e( () ) を実⾏する ◦ 要素をもう追加しないと確定したときに使うと、メモリ 使⽤量を減らせる
c E E g ge et t( (i in nt t i in nd de ex x) ) { { O Ob bj je ec ct ts s. .c ch he ec ck kI In nd de ex x( (i in nd de ex x, , t th hi is s. .s si iz ze e) ); ; / // / 1 1 r re et tu ur rn n ( (E E) ) t th hi is s. .e el le em me en nt tD Da at ta a[ [i in nd de ex x] ]; ; / // / 2 2 } } 1. 範囲外(i in nd de ex x < < 0 0 または i in nd de ex x > >= = s si iz ze e)の場合 ◦ IndexOutOfBoundsException をスロー 2. t th hi is s. .e el le em me en nt tD Da at ta a[ [i in nd de ex x] ] を return
c E E r re em mo ov ve e( (i in nt t i in nd de ex x) ) { { O Ob bj je ec ct ts s. .c ch he ec ck kI In nd de ex x( (i in nd de ex x, , s si iz ze e) ); ; f fi in na al l O Ob bj je ec ct t[ [] ] e es s = = e el le em me en nt tD Da at ta a; ; E E o ol ld dV Va al lu ue e = = ( (E E) ) e es s[ [i in nd de ex x] ]; ; f fa as st tR Re em mo ov ve e( (e es s, , i in nd de ex x) ); ; / // / (次ページ参照) r re et tu ur rn n o ol ld dV Va al lu ue e; ; } }
va at te e v vo oi id d f fa as st tR Re em mo ov ve e( (O Ob bj je ec ct t[ [] ] e es s, , i in nt t i i) ) { { m mo od dC Co ou un nt t+ ++ +; ; f fi in na al l i in nt t n ne ew wS Si iz ze e; ; i if f ( (( (n ne ew wS Si iz ze e = = t th hi is s. .s si iz ze e - - 1 1) ) > > i i) ) S Sy ys st te em m. .a ar rr ra ay yc co op py y( (e es s, , i i + + 1 1, , e es s, , i i, , n ne ew wS Si iz ze e - - i i) ); ; e es s[ [s si iz ze e = = n ne ew wS Si iz ze e] ] = = n nu ul ll l; ; } }
c b bo oo ol le ea an n c co on nt ta ai in ns s( (O Ob bj je ec ct t o o) ) { { r re et tu ur rn n i in nd de ex xO Of f( (o o) ) > >= = 0 0; ; } } → i in nd de ex xO Of f( (O Ob bj je ec ct t o o) ) を呼ぶだけ
i in nt t i in nd de ex xO Of f( (O Ob bj je ec ct t o o) ) { { r re et tu ur rn n i in nd de ex xO Of fR Ra an ng ge e( (o o, , 0 0, , s si iz ze e) ); ; } } i in nt t i in nd de ex xO Of fR Ra an ng ge e( (O Ob bj je ec ct t o o, , i in nt t s st ta ar rt t, , i in nt t e en nd d) ) { { O Ob bj je ec ct t[ [] ] e es s = = e el le em me en nt tD Da at ta a; ; i if f ( (o o = == = n nu ul ll l) ) { { / // / 引数が n nu ul ll l の検索処理(次ページ) } } e el ls se e { { / // / 引数が n nu ul ll l 以外の検索処理(次々ページ) } } r re et tu ur rn n - -1 1; ; / // / 見つからなかった } }
の検索処理 f fo or r ( (i in nt t i i = = s st ta ar rt t; ; i i < < e en nd d; ; i i+ ++ +) ) { { i if f ( (e es s[ [i i] ] = == = n nu ul ll l) ) { { r re et tu ur rn n i i; ; } } } } • 先頭から順に、要素が n nu ul ll l か確認 ◦ n nu ul ll l なら、そのインデックスを return
の検索処理 f fo or r ( (i in nt t i i = = s st ta ar rt t; ; i i < < e en nd d; ; i i+ ++ +) ) { { i if f ( (o o. .e eq qu ua al ls s( (e es s[ [i i] ]) )) ) { { r re et tu ur rn n i i; ; } } } } • 先頭から順に、引数のオブジェクトの e eq qu ua al ls s メソッドで 判定 ◦ 戻り値が t tr ru ue e なら、そのインデックスを return
b bo oo ol le ea an n e eq qu ua al ls s( (O Ob bj je ec ct t o o) ) { { i if f ( (o o = == = t th hi is s) ) { { r re et tu ur rn n t tr ru ue e; ; / // / 1 1 } } i if f ( (! !( (o o i in ns st ta an nc ce eo of f L Li is st t) )) ) { { r re et tu ur rn n f fa al ls se e; ; / // / 2 2 } } / // / 次ページへ 1. 同じオブジェクトなら t tr ru ue e 2. ⽐較対象が List でなければ f fa al ls se e
in nt t e ex xp pe ec ct te ed dM Mo od dC Co ou un nt t = = m mo od dC Co ou un nt t; ; b bo oo ol le ea an n e eq qu ua al l = = ( (o o. .g ge et tC Cl la as ss s( () ) = == = A Ar rr ra ay yL Li is st t. .c cl la as ss s) ) ? ? e eq qu ua al ls sA Ar rr ra ay yL Li is st t( (( (A Ar rr ra ay yL Li is st t< <? ?> >) ) o o) ) : : e eq qu ua al ls sR Ra an ng ge e( (( (L Li is st t< <? ?> >) ) o o, , 0 0, , s si iz ze e) ); ; / // / 1 1 c ch he ec ck kF Fo or rC Co om mo od di if fi ic ca at ti io on n( (e ex xp pe ec ct te ed dM Mo od dC Co ou un nt t) ); ; / // / 2 2 r re et tu ur rn n e eq qu ua al l; ; } } 1. ⽐較対象が ArrayList かどうかで分岐 (Java 11 〜) 2. ⽐較処理中に m mo od dC Co ou un nt t が変わっていた場合 ◦ C Co on nc cu ur rr re en nt tM Mo od di if fi ic ca at ti io on nE Ex xc ce ep pt ti io on n をスロー
b bo oo ol le ea an n e eq qu ua al ls sA Ar rr ra ay yL Li is st t( (A Ar rr ra ay yL Li is st t< <? ?> > o ot th he er r) ) { { f fi in na al l i in nt t o ot th he er rM Mo od dC Co ou un nt t = = o ot th he er r. .m mo od dC Co ou un nt t; ; f fi in na al l i in nt t s s = = s si iz ze e; ; b bo oo ol le ea an n e eq qu ua al l; ; i if f ( (e eq qu ua al l = = ( (s s = == = o ot th he er r. .s si iz ze e) )) ) { { / // / 1 1 / // / 各要素の比較処理(後述) } } o ot th he er r. .c ch he ec ck kF Fo or rC Co om mo od di if fi ic ca at ti io on n( (o ot th he er rM Mo od dC Co ou un nt t) ); ; / // / 2 2 r re et tu ur rn n e eq qu ua al l; ; } }
ls se e で確定) 2. ⽐較処理中に⽐較対象の m mo od dC Co ou un nt t が変わっていた場合 ◦ C Co on nc cu ur rr re en nt tM Mo od di if fi ic ca at ti io on nE Ex xc ce ep pt ti io on n をスロー
je ec ct t[ [] ] o ot th he er rE Es s = = o ot th he er r. .e el le em me en nt tD Da at ta a; ; f fi in na al l O Ob bj je ec ct t[ [] ] e es s = = e el le em me en nt tD Da at ta a; ; i if f ( (s s > > e es s. .l le en ng gt th h | || | s s > > o ot th he er rE Es s. .l le en ng gt th h) ) { { / // / 1 1 t th hr ro ow w n ne ew w C Co on nc cu ur rr re en nt tM Mo od di if fi ic ca at ti io on nE Ex xc ce ep pt ti io on n( () ); ; } } f fo or r ( (i in nt t i i = = 0 0; ; i i < < s s; ; i i+ ++ +) ) { { i if f ( (! !O Ob bj je ec ct ts s. .e eq qu ua al ls s( (e es s[ [i i] ], , o ot th he er rE Es s[ [i i] ]) )) ) { { / // / 2 2 e eq qu ua al l = = f fa al ls se e; ; b br re ea ak k; ; } } } }
rr re en nt tM Mo od di if fi ic ca at ti io on nE Ex xc ce ep pt ti io on n をスロー 2. 配列をループ ◦ O Ob bj je ec ct ts s. .e eq qu ua al ls s( (e es s[ [i i] ], , o ot th he er rE Es s[ [i i] ]) ) で⽐較 引数 a, b が等しい場合は t tr ru ue e を返す(以下のいずれか) • 同じオブジェクト(a a = == = b b) • 引数が両⽅とも n nu ul ll l • a a ! != = n nu ul ll l かつ a a. .e eq qu ua al ls s( (b b) ) Objects.equals(a,b)
al l i in nt t e ex xp pe ec ct te ed dM Mo od dC Co ou un nt t = = m mo od dC Co ou un nt t; ; b bo oo ol le ea an n e eq qu ua al l = = ( (o o. .g ge et tC Cl la as ss s( () ) = == = A Ar rr ra ay yL Li is st t. .c cl la as ss s) ) ? ? e eq qu ua al ls sA Ar rr ra ay yL Li is st t( (( (A Ar rr ra ay yL Li is st t< <? ?> >) ) o o) ) : : e eq qu ua al ls sR Ra an ng ge e( (( (L Li is st t< <? ?> >) ) o o, , 0 0, , s si iz ze e) ); ; c ch he ec ck kF Fo or rC Co om mo od di if fi ic ca at ti io on n( (e ex xp pe ec ct te ed dM Mo od dC Co ou un nt t) ); ; r re et tu ur rn n e eq qu ua al l; ; } }
e eq qu ua al ls sR Ra an ng ge e( (L Li is st t< <? ?> > o ot th he er r, , i in nt t f fr ro om m, , i in nt t t to o) ) { { f fi in na al l O Ob bj je ec ct t[ [] ] e es s = = e el le em me en nt tD Da at ta a; ; v va ar r o oi it t = = o ot th he er r. .i it te er ra at to or r( () ); ; f fo or r ( (; ; f fr ro om m < < t to o; ; f fr ro om m+ ++ +) ) { { i if f ( (! !o oi it t. .h ha as sN Ne ex xt t( () ) | || | ! !O Ob bj je ec ct ts s. .e eq qu ua al ls s( (e es s[ [f fr ro om m] ], , o oi it t. .n ne ex xt t( () )) )) ) { { r re et tu ur rn n f fa al ls se e; ; } } } } r re et tu ur rn n ! !o oi it t. .h ha as sN Ne ex xt t( () ); ; } }
ls se e を return 2. ループの終了時点で、 ◦ ⽐較対象の要素が残っている→ f fa al ls se e を return ◦ ⽐較対象の要素が残っていない → t tr ru ue e を return ⽐較対象のリストの s si iz ze e( () ) の実装が O(n) の可能性があるため サイズの⽐較はしない
pa ac ci it ty y か 現在の容量の 1.5倍(⼤きい⽅) • ただし、I In nt te eg ge er r. .M MA AX X_ _V VA AL LU UE E - - 8 8 を超える場合 ◦ I In nt te eg ge er r. .M MA AX X_ _V VA AL LU UE E - - 8 8 で、以降は現在の容量 + 1 • さらに I In nt te eg ge er r. .M MA AX X_ _V VA AL LU UE E(= 2,147,483,647)を超える なら、OutOfMemoryError をスロー 1 10 0 → 1 15 5 → 2 22 2 → 3 33 3 → 4 49 9 → … …中略… … → 1 17 79 96 63 35 57 74 45 52 2 → 2 21 14 47 74 48 83 36 63 39 9 → 2 21 14 47 74 48 83 36 64 40 0 → 2 21 14 47 74 48 83 36 64 41 1 → … …中略… … → 2 21 14 47 74 48 83 36 64 47 7 → O Ou ut tO Of fM Me em mo or ry yE Er rr ro or r
_M MA AX X_ _A AR RR RA AY Y_ _L LE EN NG GT TH H という定数値 ◦ 作成できる配列の⻑さ上限ギリギリの値 (JDK-6933217) • Java ⾔語仕様上は I In nt te eg ge er r. .M MA AX X_ _V VA AL LU UE E まで • しかし、JVM の実装によっては I In nt te eg ge er r. .M MA AX X_ _V VA AL LU UE E に近い⻑さ の配列を割り当てようとした場合、ヒープの空きに関わらず OutOfMemoryError("Requested array size exceeds VM limit")をスロー する • I In nt te eg ge er r. .M MA AX X_ _V VA AL LU UE E - - 8 8 なら、どの JVM でも⼤丈夫 配列の⻑さの上限
to split in two different cases the following ArrayList constructor in the OpenJDK code? - Stack Overflow ◦ https://stackoverflow.com/q/77574918/1932017