質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

Q&A

2回答

510閲覧

kotlinの繰り返し処理でuntilを使いたい

tera877

総合スコア9

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

0グッド

0クリップ

投稿2023/06/02 05:19

編集2023/06/03 21:20

イメージ説明untilを使った繰り返しを実行できるようにしたい。

前提

短いコードです。可変のリストを作り、for文で回しながら、中身が文字列の2だった場合に、そのインデックスの要素をリストから消去するといったことをしたいです。

この場合、lsit.sizeは3です。untilを使って、0から3未満まで回しているので、インデックスも0,1,2となるはずです。サイズが3なので何も問題はないように思えてしまいます。しかしインデックスを超えているというエラーが出ます。これはどうしてでしょうか。

発生している問題・エラーメッセージ

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 2 out of bounds for length 2 at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:100) at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:106) at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:302) at java.base/java.util.Objects.checkIndex(Objects.java:385) at java.base/java.util.ArrayList.get(ArrayList.java:427) at MainKt.main(Main.kt:6) at MainKt.main(Main.kt)

該当のソースコード

kotlin

1fun main() { 2 val list: MutableList<String> = mutableListOf("1", "2", "3") 3 4 5 for (i in 0 until list.size) { 6 if (list[i] == "2") { 7 list.removeAt(i) 8 } 9 } 10 println(list) 11}

試したこと

list.size-1にすると正常に動きました。しかしどうしてそうなるのかが理解できません。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

episteme

2023/06/02 05:39 編集

list.size は 3 だから i = 0, 1, 2, 3 となり、list[3] でコケるのでは? [追記] そうじゃなかった...
tera877

2023/06/02 05:26

やはりそうですよね。今画像を添付したのですが、InteliJでUntilの部分を見ると、list.sizeが<記号で書かれており、3は含まれないという意味だと思うのですが、どこか私の解釈が間違っているのでしょうか
episteme

2023/06/02 05:27

kotlinよう知らんのですが、loop内で i をプリントして挙動を観察してはいかが?
tera877

2023/06/02 05:28

また、removeを使わずに、普通に0 until list.sizeをやって出力するとエラーになりません。一応untilの最後に3は含まれていないと思います。もしかしたらremoveが原因かもしれません。
1T2R3M4

2023/06/02 05:31

remove した時点でlistが[1,3]となってる状態で list[2]にアクセスしに行くからでは。
jimbe

2023/06/02 05:44 編集

想像ですが、 until 関数の評価が(ループ毎では無く)最初だけで、 for の開始時点で i は 0~2 の値を取ることは確定し、 removeAt をしたら list[2] は list[1] に移動するので list[2] は無くなりますが i=2 のループも行ってしまう為に list[i] で例外になるのでしょう。
episteme

2023/06/02 05:42 編集

removeAt のついでに i を-1 できるなら解決かな? (kotlinでloop変数を書き換えることができるのかしらんけど)
jimbe

2023/06/02 05:45

>i を-1 i はインデックスでは無くて 0 until list.size の集合の要素です。
episteme

2023/06/02 05:47

until 関数の評価がループのたびに行われたとしても、 removeAtされた直後の要素はskipされるので正しい動作は望めませんよね。
episteme

2023/06/02 05:49

> i はインデックスでは無くて 0 until list.size の集合の要素です。 あー、pythonの range(list.size) と同じってことか。
guest

回答2

0

Kotlin

1for (i in 0 until list.size) { 2 if (list[i] == "2") { 3 list.removeAt(i) // removeAtで要素が削除されると list.size が変化する(ひとつ少なくなる) 4 } 5}

投稿2023/06/02 05:32

episteme

総合スコア16614

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

i=1の要素を消したときにリストの要素が2つに減りますので、
i=2の要素にアクセスするときには範囲外になります

投稿2023/06/02 05:29

ozwk

総合スコア13512

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tera877

2023/06/02 05:46

リストの要素1を消去した時点で、要素2は1のところに自動的に詰められないのでしょうか。リスト1を消去した後で1にアクセスしようとするためにエラーになるというのはわかったのですが、解決策が見つかりません。助言をいただけないでしょうか
ozwk

2023/06/02 05:49

一般には別のリストに要素を足していって、ループを抜けたら元のリスト変数に代入したり、 そもそもループじゃなくてfilterなどリスト操作関数を使って元のリスト変数に代入とかします。
ozwk

2023/06/02 05:51 編集

> リスト1を消去した後で1にアクセスしようとするためにエラーになる いいえ、リストの1番目の要素を消去した後で、リストの2番目(詰めたから存在しない)にアクセスしようとしてエラーになっています
jimbe

2023/06/02 05:51

while 等で書けば良いのでは。
episteme

2023/06/02 05:53

0からlist.size-1方向(増加)に じゃなくて list.size-1から0方向(減少)に listを走査してはいかが?
jimbe

2023/06/02 15:25

>list.size-1から0方向(減少) グットを送りたいです
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問