これは私が最近受けた面接での質問です。このブログではこの質問を要約して共有します。 1. 初心者が陥りがちな間違いおそらく多くの初心者(当時の私も含めて、笑)は、まず次のようなことを書こうと考えるでしょう。 パブリック静的voidメイン(String[] args) { リスト<String> プラットフォームリスト = 新しい ArrayList<>(); platformList.add("博客园"); プラットフォームリストに「CSDN」を追加します。 プラットフォームリストに「ナゲット」を追加します。 for (文字列プラットフォーム:プラットフォームリスト) { if (platform.equals("博客园")) { プラットフォームを削除します。 } } System.out.println(プラットフォームリスト); } 自信を持って実行してみましたが、 なぜこのようなことが起こるのかと混乱して疑問に思っていませんか? まず、上記のコードによって生成されたバイトコードを見てみましょう。 このことから、foreach ループが実際に実行されると、実際には Iterator が使用され、使用されるコア メソッドは hasnext() と next() であることがわかります。 それでは、ArrayList クラスの Iterator がどのように実装されているかを見てみましょう。 次の要素を取得するために next() メソッドが呼び出されると、コードの最初の行は checkForComodification(); を呼び出すことであり、このメソッドのコアロジックは 2 つの変数 modCount と expectedModCount の値を比較することであることがわかります。 上記の例では、最初は modCount と expectedModCount の値が両方とも 3 であるため、要素「博客园」を初めて取得する際に問題はありませんが、次のコード行が実行されると: プラットフォームを削除します。 modCountの値が4に変更されます。 そのため、2 回目に要素を取得するときに、modCount と expectedModCount の値が等しくないため、エラーがスローされます。 foreach を使用してこれを実現することはできないので、どのように実装すればよいでしょうか? 主な方法は3つあります。
次に一つずつ説明していきます。 2. Iteratorのremove()メソッドを使用するIterator を使用した remove() メソッドの実装は次のとおりです。 パブリック静的voidメイン(String[] args) { リスト<String> プラットフォームリスト = 新しい ArrayList<>(); platformList.add("博客园"); プラットフォームリストに「CSDN」を追加します。 プラットフォームリストに「ナゲット」を追加します。 イテレータ<String> iterator = platformList.iterator(); (イテレータ.hasNext()) の間 { 文字列プラットフォーム = iterator.next(); if (platform.equals("博客园")) { イテレータを削除します。 } } System.out.println(プラットフォームリスト); } 出力は次のようになります。
iterator.remove() が使用できるのはなぜですか?ソースコードを見てみましょう: 要素が削除されるたびに、modCountの値がexpectedModCountに再割り当てされ、2つの変数が等しくなり、トリガーされないことがわかります。 3. forループを使用して正の順序で走査するfor ループを使用した前方トラバーサルの実装は次のとおりです。 パブリック静的voidメイン(String[] args) { リスト<String> プラットフォームリスト = 新しい ArrayList<>(); platformList.add("博客园"); プラットフォームリストに「CSDN」を追加します。 プラットフォームリストに「ナゲット」を追加します。 (int i = 0; i < platformList.size(); i++) の場合 { 文字列項目 = platformList.get(i); if (item.equals("博客园")) { プラットフォームリストを削除します(i); i = i - 1; } } System.out.println(プラットフォームリスト); } この実装は配列の添字で削除するだけなので比較的理解しやすいのですが、要素を削除した後は添字の値を修正する必要があるという注意点があります。 i = i - 1; 下付き文字の値を修正する必要があるのはなぜですか?最初の要素の添え字は次のようになります。 最初のループで要素「博客园」を削除すると、要素の添え字は次のようになります。 2 番目のループでは、i の値は 1 です。これは、要素 "Nuggets" が取得され、要素 "CSDN" がスキップされることを意味します。したがって、要素を削除した後、添え字を修正する必要があります。これは、上記のコードで i = i - 1; の目的でもあります。インタビューの質問の詳細については、WeChatのサブスクリプション番号Jiangjijiをフォローしてインタビューに返信してください。 4. forループを使用して逆順に走査するfor ループを使用した逆方向トラバーサルの実装は次のとおりです。 パブリック静的voidメイン(String[] args) { リスト<String> プラットフォームリスト = 新しい ArrayList<>(); platformList.add("博客园"); プラットフォームリストに「CSDN」を追加します。 プラットフォームリストに「ナゲット」を追加します。 (int i = platformList.size() - 1; i >= 0; i--) { 文字列項目 = platformList.get(i); if (item.equals("ナゲット")) { プラットフォームリストを削除します(i); } } System.out.println(プラットフォームリスト); } この実装は、for ループを使用して前方順にトラバースするのと似ていますが、先頭の要素の添え字は次のようになるため、添え字を修正する必要はありません。 最初のループで要素「Nuggets」を削除すると、要素の添え字は次のようになります。 2 番目のループでは、i の値が 1 であるため、要素 "CSDN" が取得され、要素がスキップされることはないため、添え字を修正する必要はありません。 そのため、2 回目に要素を取得するときに、modCount と expectedModCount の値が等しくないため、エラーがスローされます。 foreach を使用してこれを実現することはできないので、どのように実装すればよいでしょうか? 主な方法は3つあります。
次に一つずつ説明していきます。 5. Iteratorのremove()メソッドを使用するIterator を使用した remove() メソッドの実装は次のとおりです。 パブリック静的voidメイン(String[] args) { リスト<String> プラットフォームリスト = 新しい ArrayList<>(); platformList.add("博客园"); プラットフォームリストにCSDNを追加します。 プラットフォームリストに「ナゲット」を追加します。 イテレータ<String> iterator = platformList.iterator(); (イテレータ.hasNext()) の間 { 文字列プラットフォーム = iterator.next(); if (platform.equals("博客园")) { イテレータを削除します。 } } System.out.println(プラットフォームリスト); } 出力は次のようになります。
iterator.remove() が使用できるのはなぜですか?ソースコードを見てみましょう: 要素が削除されるたびに、modCountの値がexpectedModCountに再割り当てされ、2つの変数が等しくなり、トリガーされないことがわかります。 6. forループを使用して正の順序で走査するfor ループを使用した前方トラバーサルの実装は次のとおりです。 パブリック静的voidメイン(String[] args) { リスト<String> プラットフォームリスト = 新しい ArrayList<>(); platformList.add("博客园"); プラットフォームリストに「CSDN」を追加します。 プラットフォームリストに「ナゲット」を追加します。 (int i = 0; i < platformList.size(); i++) の場合 { 文字列項目 = platformList.get(i); if (item.equals("博客园")) { プラットフォームリストを削除します(i); i = i - 1; } } System.out.println(プラットフォームリスト); } この実装は配列の添字で削除するだけなので比較的理解しやすいのですが、要素を削除した後は添字の値を修正する必要があるという注意点があります。 i = i - 1; 下付き文字の値を修正する必要があるのはなぜですか?最初の要素の添え字は次のようになります。 最初のループで要素「博客园」を削除すると、要素の添え字は次のようになります。 2 番目のループでは、i の値は 1 です。これは、要素 "Nuggets" が取得され、要素 "CSDN" がスキップされることを意味します。したがって、要素を削除した後、添え字を修正する必要があります。これは、上記のコードで i = i - 1; の目的でもあります。インタビューの質問の詳細については、WeChatのサブスクリプション番号Jiangjijiをフォローしてインタビューに返信してください。 7. forループを使用して逆順に走査するfor ループを使用した逆方向トラバーサルの実装は次のとおりです。 パブリック静的voidメイン(String[] args) { リスト<String> プラットフォームリスト = 新しい ArrayList<>(); platformList.add("博客园"); プラットフォームリストに「CSDN」を追加します。 プラットフォームリストに「ナゲット」を追加します。 (int i = platformList.size() - 1; i >= 0; i--) { 文字列項目 = platformList.get(i); if (item.equals("ナゲット")) { プラットフォームリストを削除します(i); } } System.out.println(プラットフォームリスト); } この実装は、for ループを使用して前方順にトラバースするのと似ていますが、先頭の要素の添え字は次のようになるため、添え字を修正する必要はありません。 最初のループで要素「Nuggets」を削除すると、要素の添え字は次のようになります。 2 番目のループでは、i の値が 1 であるため、要素 "CSDN" が取得され、要素がスキップされることはないため、添え字を修正する必要はありません。 いいね機能にMySQLとRedisのどちらを使うべきかについてはこれで終わりです。MySQL\Redisのいいね機能に関する関連コンテンツについては、123WORDPRESS.COMの過去の記事を検索するか、以下の関連記事を引き続きご覧ください。今後とも123WORDPRESS.COMをよろしくお願いいたします。 以下もご興味があるかもしれません:
|
<<: Webフロントエンド開発エンジニアが習得すべきコアスキル
>>: HTML のボタン タグをクリックしてページにジャンプする 3 つの方法
この記事では、Webオンラインチャットを実装するためのVueの具体的なコードを参考までに紹介します。...
1. データベースとデータベースインスタンスMySQL の研究では、データベースとデータベース イン...
mysql クエリ制御ステートメントフィールド重複排除 **キーワード: 明確** 構文: テーブル...
必要なファイルをインストールする Yum インストール openssl-* -yデータベースインデッ...
毎日jQueryプラグイン - 検索履歴を作成するためのものです。参考までに、具体的な内容は次のとお...
最近コンピュータを再インストールした後、最新バージョンのみをインストールするという強迫観念に基づいて...
この記事では、参考までにMySQL 5.7.13 winx64のインストールと設定方法のグラフィック...
1. はじめにデータベース内のデータ量が一定レベルに達すると、システムパフォーマンスのボトルネックを...
参考までにMySQL 8.0.22をダウンロードしてインストールしてください。具体的な内容は次のとお...
目次1. プロトタイプとプロトタイプチェーンの平等関係を理解する2: プロトタイプとプロトタイプ チ...
興味深い発見:合計 1000 件のレコードを含むテーブルがあります。クエリ ステートメントは次のよう...
docker リモート API を学習した学生であれば、ポート 2375 についてよくご存知だと思い...
準備Windows Server 2008 R2 Enterprise (2.40GH、8GB、64...
目次算術演算子異常状況1: 特殊値リテラルを含む操作異常な状況 2: 他の種類のデータが数学演算に関...
目次1. Linuxシステムの操作レベルの概要2. 実行レベルを確認する3. 現在のシステムの動作レ...