Java:forループの初期化で複数の変数を初期化しますか?


91

異なるタイプの2つのループ変数が必要です。これを機能させる方法はありますか?

@Override
public T get(int index) throws IndexOutOfBoundsException {
    // syntax error on first 'int'
    for (Node<T> current = first, int currentIndex; current != null; 
            current = current.next, currentIndex++) {
        if (currentIndex == index) {
            return current.datum;
        }
    }
    throw new IndexOutOfBoundsException();
}

firstですか?どこにも宣言されていません。クラスのメンバーですか?
extraneon

7
以下の1つの回答を受け入れる必要があります
Mr_and_Mrs_D 2013

また、Cとは異なり、Javaにはコンマ演算子:stackoverflow.com/questions/12601596/…がありません。これにより、異なるタイプの2つの変数を初期化できます(宣言はできません)。
CiroSantilli郝海东冠事病六四事件法轮功2015

@Nick Heiner以下の回答のいずれかを承認済みとしてマークしていただけますか?
ジェームス・モンガー

回答:


105

ステートメントの初期化は、forローカル変数宣言の規則に従います

これは合法です(ばかげている場合):

for (int a = 0, b[] = { 1 }, c[][] = { { 1 }, { 2 } }; a < 10; a++) {
  // something
}

ただし、必要に応じて個別の型Nodeint型を宣言しようとすることは、ローカル変数の宣言には適していません。

次のようなブロックを使用して、メソッド内の追加の変数のスコープを制限できます。

{
  int n = 0;
  for (Object o = new Object();/* expr */;/* expr */) {
    // do something
  }
}

これにより、メソッドの他の場所で変数を誤って再利用することがなくなります。


10
言語設計者がこの一見不必要な制約を実装した理由を誰かが知っていますか?
Jeff Axelrod

@ glenviewjeff-それは別の質問として尋ねるのが最善でしょう。
マクダウェル

2
JavaはC ++をモデルにしたため@JeffAxelrodは、おそらく歴史的な理由のために...この記事を参照してください。stackoverflow.com/questions/2687392/...
クリストフRoussy

3
ブロックを使用するための+1、私はそれらを頻繁に使用しますが、愚かな間違いをするよりも優れています
Christophe Roussy 2013

18

あなたはこれを好きになることはできません。同じタイプの複数の変数を使用するかfor(Object var1 = null, var2 = null; ...)、他の変数を抽出してforループの前に宣言します。


9

変数宣言(Node<T> currentint currentIndex)をループの外に移動するだけで、機能するはずです。このようなもの

int currentIndex;
Node<T> current;
for (current = first; current != null; current = current.next, currentIndex++) {

または多分さえ

int currentIndex;
for (Node<T> current = first; current != null; current = current.next, currentIndex++) {

1
どちらもコンパイルされません。使用する前に変数を初期化する必要があります。
unbeli 2010

@unbeliええと、私は手動のコードコンパイルで運動していませんでした:)私はただアイデアを与えたかっただけです。
Nikita Rybak 2010

3
@unbeli:明確にするために:currentIndexを初期化する必要があります。Nikitaが最初に行うのは「currentIndex ++」です。これは自然に質問を引き起こしますが、何をインクリメントしますか?最初の使用はそれを最初に設定することなので、電流は問題ありません。
ジェイ

通常、forループでインクリメントをより適切に書き込むには、コンパイラから必要な表記var ++として++ varを使用して、varのコンテンツを複製してからインクリメントして、式の結果として返す必要がありますが、誰もそれを望んでいません。もちろん、コンパイラはそれを最適化しますが、それは他の人が片付けるのを待って道路にゴミを投げるようなものです。
チャッキー2013

5

初期化ブロックで宣言された変数は同じタイプである必要があります

設計に従って、forループ内のさまざまなデータ型を初期化することはできません。小さな例を挙げています。

for(int i=0, b=0, c=0, d=0....;/*condition to be applied */;/*increment or other logic*/){
      //Your Code goes here
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.