Java入門 基本情報技術者へのステップアップ – Map, List, StringBuilder – #プログラム初心者からの脱出②

基本情報技術者試験に必要となるコレクションクラス群(Map、List)や文字列操作(StringBuilder)について学びましょう。

コレクション(List)

Listのクラスは、大きさを決めていない配列と思ってください。

定義はインターフェイスのListを利用しますが、newする実体はArrayListクラスを使用することが多いです。

実体クラスで定義をしたり、インターフェースでオブジェクトを生成しようとするとプログラミング初心者(全く知らない人)と思われます。

import java.util.ArrayList;
import java.util.List;

class ListTest{
  public static void main(String args[]){
  
    // これは正しい。
    List<String> countries = new ArrayList<String>();

    countries.add("日本");
    countries.add("ブラジル");
    countries.add("イングランド");

    // こんなことをしているとオブジェクト指向の知識がないと思われます。
    // 定義はインターフェースを利用しないと、
    // 状況によって、ArrayList や LinkedList などの使い分けや拡張ができなくなります。
    // List、ArrayList、LinkedList が、それぞれ持っているメソッドは、ほぼ同じ。
    ArrayList<String> drinks = new ArrayList<String>();

    drinks.add("コーヒー");
    drinks.add("紅茶");
    
    // インターフェースはオブジェクトを生成できない
    // *コンパイルエラーが発生    
    List<String> foods = new List<String>();
  }
}

addメソッドで要素を加えて、getメソッドで取得します。

import java.util.ArrayList;
import java.util.List;

class ListTest{
  public static void main(String args[]){
  
    // オブジェクトの生成と値のセット
    List<String> countries = new ArrayList<String>();

    countries.add("日本");
    countries.add("ブラジル");
    countries.add("イングランド");
    countries.add("ポルトガル");
    countries.add("フランス");

    // 値を取得
    String country = countries.get(2);
    System.out.println(country);
  }
}

// -----
// 出力結果(System.out.println)
// イングランド

ArrayListクラスについては、JavaDocも見ておきましょう。

https://docs.oracle.com/javase/jp/21/docs/api/java.base/java/util/AbstractList.html

コレクション(Map)

Mapクラスは、大きさの決まっていない連想配列(キーと値のセット)と思ってください。

定義はインターフェイスのMapを利用しますが、newする実体はHashMapクラスを使用することが多いです。

実体クラスで定義をしたり、インターフェースでオブジェクトを生成しようとするとプログラミング初心者(全く知らない人)と思われます。

import java.util.HashMap;
import java.util.Map;

class MapTest{
  public static void main(String args[]){
  
    // これは正しい。
    Map<String,String> fruits = new HashMap<String,String>();

    fruits.put("apple", "りんご");
    fruits.put("orange", "みかん");
    fruits.put("banana", "ばなな");  
    
    // 考え方は、List と同じ。
    // こんなことをしているとオブジェクト指向の知識がないと思われます。
    HashMap<String,String> birds = new HashMap<String,String>();

    birds.put("parakeet", "インコ");
    birds.put("canary", "カナリア");

    // インターフェースはオブジェクトを生成できない
    // *コンパイルエラーが発生
    Map<String,String> animals = new Map<String,String>();
  }
}

putメソッドで要素を加えて、getメソッドで要素を取得します。特定のキーがあるかどうかを調べるためには、containsKeyメソッドを使用します。

import java.util.HashMap;
import java.util.Map;

class MapTest{
  public static void main(String args[]){
  
    // オブジェクトの生成と値のセット
    Map<String,String> fruits = new HashMap<String,String>();

    fruits.put("apple", "りんご");
    fruits.put("orange", "みかん");
    fruits.put("banana", "ばなな");

    // キーを探す
    if (fruits.containsKey("apple")){
      System.out.println(fruits.get("apple"));
    }else{
      System.out.println("指定したキーは存在しません");
    }
  }
}

// -----
// 出力結果(System.out.println)
// りんご

HashMapクラスについては、JavaDocも見ておきましょう。

https://docs.oracle.com/javase/jp/21/docs/api/java.base/java/util/HashMap.html

文字列結合(StringBuilder)

Javaで文字列を結合を簡単に行うには、下記のように行います。

class StringTest {
  public static void main(String args[]){
  
    // 3つの文字列をつなぐ
    String str = "abc" + "def" + "ghi";
    System.out.println(str);
  }
}

// -----
// 出力結果(System.out.println)
// abcdefghi

簡単なプログラムであれば問題はないのですが、この方法は実行速度とメモリの使用量を考えると問題があると言われています。

具体的には、下記のようになります。

class StringTest {
  public static void main(String args[]){
    /*
     * 最低3回は文字列オブジェクトを生成してしまっている…!
     */
    String str = "abc"; // ここで文字列オブジェクトを生成
    str = str + "def";  // ここで文字列オブジェクトを生成
    str = str + "ghi";  // ここで文字列オブジェクトを生成
    System.out.println(str);
  }
}

// -----
// 出力結果(System.out.println)
// abcdefghi
//
// *期待した結果は得られるが、不要なオブジェクトをたくさん生成している…!

上記のように文字列を「+(プラス)」で繋げてしまう人は、プログラミングの基本を理解していない人と判断されます。

多くの場合、文字列結合では専用のクラス(StringBuilder)が準備されていますので、こちらを使うことが通例となっています。

appendメソッドで文字列を追加して、Stringオブジェクトを生成します。

class StringTest {
  public static void main(String args[]){
    StringBuilder sb = new StringBuilder();
    sb.append("abc");
    sb.append("def");
    sb.append("ghi");
    System.out.println(new String(sb));
    //StringBuilderを文字列にするには次の方法もあります。
    //System.out.println(sb.toString());
  }
}

// -----
// 出力結果(System.out.println)
// abcdefghi

さらに、別ページでも紹介していますが、「==」と「equals」では全く結果が異なります。

class StringTest {
  public static void main(String args[]){
    // 文字列を生成
    StringBuilder builder = new StringBuilder();
    builder.append("あいう");
    builder.append("えお");
    builder.append("かきくけこ");
    String str = builder.toString();

    //.結合結果が同じになる文字列を別に準備
    String test = "あいうえおかきくけこ";
    
    //.イコールメソッドを利用
    System.out.println(str.equals(test));
    // イコール記号で比較
    System.out.println(str == test);
  }
}

StringBuilderクラスについては、JavaDocも見ておきましょう。

https://docs.oracle.com/javase/jp/21/docs/api/java.base/java/lang/StringBuilder.html

ラッパークラス

Javaでは基本のデータ型があり、数値や文字を格納したり演算子と組み合わせることで様々なことができます。しかし、ただ基本データ型はクラスのようにメソッドがありませんので、型変換などメソッドが準備されていません。

そこで基本データ型の値を持つことができ、様々なメソッドを持ったクラスが用意されています。これをラッパークラスと呼びます。

ListクラスやMapクラスで数値などを扱う場合、このラッパークラスを使用します。

基本データ型ラッパークラス
booleanBoolean
charCharacter
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble

拡張for文(foreach文)

ListクラスやMapクラスの全ての要素を取得する場合に拡張for文が便利です。

例えば、配列の場合は次のように使います。

class ForTest1{
  public static void main(String args[]){
    int data[] = {85, 72, 89};
    for (int seiseki: data){
      System.out.println(seiseki);
    }
  }
}
// -----
// 出力結果(System.out.println)
// 85
// 72
// 89

Listクラスの場合は次のように使います。

import java.util.ArrayList;
import java.util.List;
class ForTest {
  public static void main(String args[]){
  
    // 
    List<String> countries = new ArrayList<String>();
    countries.add("日本");
    countries.add("ブラジル");
    countries.add("イングランド");
    countries.add("ポルトガル");
    countries.add("フランス");
    
    // 順に表示させる
    for(String country : list) {
      System.out.println(country);
    }
  }
}
// -----
// 出力結果(System.out.println)
// 日本
// ブラジル
// イングランド
// ポルトガル
// フランス

今日は、ここまでとしましょう。