SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

japan.internet.com翻訳記事

J2SE 5.0のコレクションの使い方を覚える

ジェネリック型とオートボクシングによって改良されたコレクションへのアクセス

拡張されたforループの利用

 これまでのJavaには、for eachループ構文がありませんでした。Visual BasicやC#などの言語にはこの構文があるので、開発者はコレクションの要素に対するループ処理を容易に行うことができます。for eachループを用いると、反復子を使わずにコレクション内部の要素を参照できます。J2SE 5.0になって(ようやく)Javaにも、従来のforループを拡張する形でfor eachループ構文が用意されました。

 この拡張されたforループは、J2SE 5.0の機能のなかでも最も期待されていたものの1つです。この機能を使えば、さきほど紹介したコードのIteratorがすっかり不要になるため、さらに簡潔なコードが得られます。拡張されたforループを使ってJ2SE 5.0用に変更したコードを以下に示します。

import java.util.*;

public class EnhancedForCollection {
  public static void main(String args[]) {
    ArrayList<String> list = new ArrayList<String>();

    list.add( new String("One") );
    list.add( new String("Two") );
    list.add( new String("Three") );
    //list.add( new StringBuffer() );

    for( String str : list  ) {
      System.out.println( str );
    }
  }
} 

 このコードでは、元のコードからIteratorwhileループが完全に削除され、次の3行になっています。

for( String str : list  ) {
   System.out.println( str );
}

 拡張されたforループの書式は次のとおりです。

for( [collection_item_type] [item_access_variable] : 
   [collection_to_be_iterated] )

 最初のパラメータであるcollection_item_type(コレクション要素の型)は、コレクション作成時に指定したジェネリック型に対応するJavaの型でなければなりません。ここで扱うコレクションは前述のArrayListなので、コレクション要素の型はStringになります。

 2番目のパラメータitem_access_variableは、アクセス変数の名前です。この変数は、コレクションに対するループ処理を繰り返す際に各コレクション要素の値を入れるためのものです。このアクセス変数の型もまた、collection_item_typeで指定したものと同じでなければなりません。

 3番目のパラメータcollection_to_be_iteratedは、繰り返し処理の対象となるコレクションを示します。この変数は、コレクション型として宣言されたものであり、かつcollection_item_typeと一致するジェネリック型を持っていなければなりません。この2つの条件を満たしていない場合は、コンパイルエラーが発生します。

プリミティブデータ型とオートボクシング

 J2SE 5.0に追加されたもう1つの重要な機能が、プリミティブデータ型のボクシングとアンボクシングを自動的に行う機能です。コレクションAPIでプリミティブデータ型の追加と参照を行うコードは複雑になりがちですが、このオートボクシング機能により、コードをかなり簡略化できます。

 ボクシングとアンボクシングについて馴染みがない方は、J2SE 5.0について知る前に、Javaがプリミティブデータ型をどのように扱うかをまず知っておく必要があります。ここでは、本題のJ2SE 5.0に入る前に、コレクションAPIでプリミティブデータ型を利用する簡単なJavaアプリケーションを紹介しましょう。

import java.util.*;

public class PrimitiveCollection {
  public static void main(String args[]) {
    ArrayList list = new ArrayList();

    // box up each integer as they are added
    list.add( new Integer(1) );
    list.add( new Integer(2) );
    list.add( new Integer(3) );
    //list.add( new StringBuffer() );

    // now iterate over the collection and unbox
    Iterator itr = list.iterator();
    while( itr.hasNext() ) {
      Integer iObj = (Integer)itr.next();
      int iPrimitive = iObj.intValue();
      System.out.println( iPrimitive );
   }
  }
}

 上記のコードは、コレクションAPIでプリミティブ型を用いるために必要な2つの手順を示しています。コレクション型は、プリミティブ型ではなくオブジェクト型を格納するため、プリミティブ型の要素を格納したいときには、適切なラッパーオブジェクトにボクシングしなければなりません。たとえば、上記のコードでは、次のようにしてintプリミティブデータ型をIntegerオブジェクトにボクシングしています。

list.add( new Integer(1) );
list.add( new Integer(2) );
list.add( new Integer(3) );

 しかし、このボクシングを行うと、コードの後の部分で、コレクションに格納されたプリミティブ型のint型変数にアクセスしようとするときに問題が起こります。プリミティブデータ型は、Integerオブジェクトとして格納されたため、コレクションから返されるときも、int型の変数ではなくIntegerオブジェクトとして返されます。そのため、ボクシングのときと逆の変換(アンボクシング)が必要になります。

Iterator itr = list.iterator();
while( itr.hasNext() ) {
Integer iObj = (Integer)itr.next();
  int iPrimitive = iObj.intValue();
  System.out.println( iPrimitive );
}

 この例の場合は、まずは各要素をIntegerオブジェクトとして取り出し、iObjとします。次に、intValueメソッドを呼び出すことで、このIntegerオブジェクトをプリミティブ型であるint型に変換します。

 J2SE 5.0のオートボクシングを使えば、コレクションでのプリミティブ型の格納と取り出しがとても容易になります。次に例を示します。

import java.util.*;

public class AutoBoxCollection {
  public static void main(String args[]) {
    ArrayList<Integer> list = new 
      ArrayList<Integer>();

    // box up each integer as it's added
    list.add( 1 );
    list.add( 2 );
    list.add( 3 );
    //list.add( new StringBuffer() );

    // now iterate over the collection
    for( int iPrimitive: list  ) {
      System.out.println( iPrimitive );
    }
  }
} 

 このオートボクシングのサンプルでは、最初にIntegerのジェネリック型を持つArrayListを作成しています。

ArrayList<Integer> list = new ArrayList<Integer>();

 Integerというラッパー型をジェネリック型とするリストを作成した後は、プリミティブ型であるint型変数を直接このリストに追加できます。

list.add( 1 );
list.add( 2 );
list.add( 3 );

 この場合、それぞれの整数をIntegerオブジェクトでラップする必要はもうありません。さらに、リスト内にある個々の要素の参照もまた容易になります。

for( int iPrimitive: list  ) {
  System.out.println( iPrimitive );
}

 この例は、拡張されたforループを使ってプリミティブデータ型のコレクションの反復処理を行う方法を示しています。ここでは、型変換の必要はなく、プリミティブ型の各変数をint型として直接取り出すことができます。つまり、オートボクシングとアンボクシングによって、プリミティブデータ型をオブジェクトと同じくらい容易にコレクションで扱うことができるのです。

まとめ

 J2SE 5.0にジェネリック型が追加されたことで、コレクションに格納するデータの型を明確に指定できるようになりました。これによって、コレクションが正しい型のオブジェクトだけを受けとることがコンパイラによって保証され、コレクションで扱われる要素の型変換が不要になります。

 また、ジェネリック型により、拡張されたforループの利用が可能になりました。この拡張されたforループは他のプログラミング言語に見られるfor each構文と同じ機能を提供しています。拡張されたforループ構文では、反復子が不要なため、コレクションの各要素に対する繰り返し処理の記述がかなり簡潔になります。

 これまで、コレクションへのプリミティブデータ型の追加は、常に面倒なものでした。int型のようなプリミティブ型をいったんIntegerオブジェクトにボクシングした後、再びint型に戻すためにアンボクシングしなければならなかったのです。オートボクシングとアンボクシングによって、この処理を開発者ではなくJava側に負担させることができ、その結果、プリミティブデータ型を持つコレクションを利用する際のソースコードはずっと読みやすいものになります。

 こうした変更によって、J2SE 5.0のコレクションデータへのアクセス方法は必然的に変化し、コレクションAPIにアクセスするためのJavaコードもずっとシンプルなものになっています。

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
japan.internet.com翻訳記事連載記事一覧

もっと読む

この記事の著者

japan.internet.com(ジャパンインターネットコム)

japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.comEarthWeb.com からの最新記事を日本語に翻訳して掲載するとともに、日本独自のネットビジネス関連記事やレポートを配信。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

Jeff Heaton(Jeff Heaton)

ライター、人工知能(AI)研究者、元大学教員。AI、仮想世界、スパイダー、ボットなどの話題を取り上げて執筆した書籍は10冊以上。Java、.Net、Silverlightを対象に、高度なニューラルネットワークおよびAIフレームワークの提供を目的とするオープンソースイニシアチブ、Encogプロジェクトを統括している。また、個人のWebサイトを管理し、人工知能とスパイダー/ボットプログラミングをはじめとする話題について情報発信を行っている。メールの宛先はjheaton@heatonresearch.com。Sun認定Javaプログラマ兼IEEEシニアメンバー。ミズーリ州セントルイスのワシントン大学情報管理修士号を持ち、セントルイス在住。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/278 2006/04/11 19:09

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー