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

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

新規登録して質問してみよう
ただいま回答率
85.37%
iteratorパターン

iteratorパターンとは、オブジェクト指向プログラミングのデザインパターンです。コンテナオブジェクトの要素を列挙する手段を独立させることによって、コンテナの内部仕様に依存しない反復子を提供することを目的とします。

Java

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

ArrayList

Java用のタグです。arrayListはListインターフェースを実装した、リサイズ可能な配列用クラスです。

Q&A

解決済

4回答

9436閲覧

Iteratorクラスのremoveメソッドの動きが分かりません…

st-access_91s

総合スコア43

iteratorパターン

iteratorパターンとは、オブジェクト指向プログラミングのデザインパターンです。コンテナオブジェクトの要素を列挙する手段を独立させることによって、コンテナの内部仕様に依存しない反復子を提供することを目的とします。

Java

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

ArrayList

Java用のタグです。arrayListはListインターフェースを実装した、リサイズ可能な配列用クラスです。

0グッド

1クリップ

投稿2016/03/06 17:43

編集2016/03/13 15:54

※申し訳ありません。仕事都合で回答への返信が大分遅れそうです。。。

以下のコードをコンパイルすると、A,B,D,Eの4つが表示されました。これについて私は、カーソルの関係(要素が繰り上がる)でA,B,Eの3つが表示されるか、スコープの関係(while文で使われているstrとfor文で使われているstrは別スコープ)でA~E全てが表示されるのではないかと考えていたのですが、なぜCだけ削除されたのでしょうか?
Iteratorクラスのremoveメソッドの動きが特殊なのかと調べたのですが、それらしい記述は見つけられませんでした。
ちなみにこのコードは、著書『Java SE7 Silver問題集』の第4章:問18の解説を参考にしたものです。

import java.util.ArrayList;
import java.util.Iterator;

public class Main {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");
list.add("D");
list.add("E");
Iterator<String> ite = list.iterator();
while(ite.hasNext()) {
String str = ite.next();
if("C".equals(str)) {
ite.remove();
}
}
for(String str : list) {
System.out.println(str);
}
}
}

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

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

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

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

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

swordone

2016/03/13 15:58

遅れる理由はいいので、何で引っかかっているのか具体的に説明してください。
st-access_91s

2016/03/26 11:55

Iteratorクラスの動きが調べてもよく分からなかったため、removeメソッドの性質やスコープの関係から、A,B,D,Eの4つが表示される理由が分からなかった次第です。皆さんの回答を整理して、段々と理解が進んできている状況です。
guest

回答4

0

Listのメソッドiteratorから生成されるIteratorは、元のListと同じコレクションを参照します。
Iteratorは元のListの要素をnextで順番に取り出し、removeは最後にnextで呼び出した要素を削除する仕組みになっています。
このコードの場合、removeで"C"が削除されたあと、Listは["A", "B", "D", "E"]という状態になり、Iteratorはあえて言うなら"B"と"D"の間にいる状態になります。while文中のstrはIteratorが返した要素を一時的に置いておいているに過ぎません。
その後のfor文で、内部では新たにIteratorが生成されています。もちろん、元のListは["A", "B", "D", "E"]の状態です。内部的にIteratorが取り出した要素がfor文中のstrに置かれ、順次出力しているだけです。

ごく自然な動きだと思うのですが、どこで引っかかっているのでしょうか?

投稿2016/03/06 18:08

swordone

総合スコア20669

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

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

st-access_91s

2016/03/26 13:00 編集

ご回答いただきありがとうございます(返信遅くなって申し訳ありません)。 カーソルの関係について、著書『Java SE7 Silver問題集』を読み直してみると、removeメソッドの動きとしてでなく拡張for文の要素取り出しの動きとしてカーソルの原理が働いているといった内容が書かれていることに気付きました。swordoneさんの回答を読み、改めてIteratorについて調べて、nextで順番に取り出す際は繰り上がりによる読み飛ばしは発生しないという考えに至りました。 また、strのスコープに囚われる必要はなく、listの要素が拡張for文処理前段階で"A", "B", "D", "E"になっていることも合点がいきました。 ちなみに改めて参照したサイトの内、参考にしたのは以下の2つです。 http://tercel-sakuragaoka.blogspot.jp/2011/06/processing.html http://www.javaroad.jp/java_collection5.htm
guest

0

ベストアンサー

下記のどちらかで考えていたが、実際は違った。なぜか…ということですね。

カーソルの関係(要素が繰り上がる)でA,B,Eの3つが表示される

 

スコープの関係(while文で使われているstrとfor文で使われているstrは別スコープ)でA~E全てが表示されるのではないか

どちらの考え方も、プリミティブ型(int,double,booleanなど)と参照型(プリミティブ型以外のすべて)の違いを明確に理解されてないように思います。

Listは参照型ですので、Iteratorに値をコピーしているわけではなく、今Listの何番目を参照しているかという情報を渡しています。

また、IteratorはListを一通り舐めるための栞(しおり)のような役目を果たしています。
今回の場合でいうと、栞が指し示す場所が"C"という文字列であったら、Listの要素を削除するという処理をしています。

たしかに、栞のスコープはListとは違いますが、栞が消えても、Listは残っているので、今回のような結果となります。

答えになっていますでしょうか?

投稿2016/03/13 19:01

編集2016/03/13 19:11
Odacchi

総合スコア907

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

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

0

オブジェクト指向のプログラムでは再利用性などを考慮してデザインパターンが用いられることがあります。
JavaでのIteratorインターフェースは、
その「Iteratorパターン」を利用できるようにするためのインターフェースの様です。

自分もまだ勉強中ですが、
デザインパターンについては下記リンク先がとても勉強になります。
TECHSCORE:デザインパターン

Iteratorインターフェースを利用することでカプセル化された状態を維持したまま、
要素を先頭から末尾まで走査するような処理を実現できる様です。

ArrayListがIteratorインターフェースを継承しているので
hasNext()で「次の要素があるか」を確認でき、
next()メソッドで参照する要素を「次へ」移すことが出来ます。
さらに、
(配列、または、)Iterableインターフェースを継承すると拡張for文が利用できます。
拡張for文では配列化されたObjectを一つずつ取り出しながら利用できます。

質問者様のソースでは
while文でIteratorで一旦、走査し、その中で"C"を削除されています。
その後、拡張for文で("C"が削除済みの)listを走査して標準出力されています。

以上、
ご参考になりますでしょうか?

投稿2016/03/07 00:35

Aeona

総合スコア396

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

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

0

ArrayListのIteratorなので、ArrayListのremoveが呼ばれます。

Iteratorについては、どういうものなのか、ソースを見ることが出来ます。
自分のPCだと
C:\Program Files\Java\jdk1.7.0_40\src.zip
を回答するとjavaのソースがあります。

Iteratorのソースを見ると remove()が宣言されているだけで
実装がないことがわかります。Interfaceクラスだからです。

Interfaceクラスななんだろう?とか疑問がわいてくれば
それを調べていくのもありです。

楽しんでHackしましょう。

投稿2016/03/06 22:05

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

st-access_91s

2016/03/26 18:23

ご回答いただきありがとうございます(返信遅くなって申し訳ありません)。 ソースを見てみましたが、Silver未取得者レベルの私にはまだまだ理解が難しいです…。 でも、もう少し実力がついたら改めてコード読み進めようと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.37%

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

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

質問する

関連した質問