Java/API

出典: フリー教科書『ウィキブックス(Wikibooks)』

Javaには標準入出力はもちろん、HTTPリクエストなどのネットワーク機能やSQL、リストやマップ、セットといったコレクション、日付や時間を扱うAPIまで存在します。 本稿ではそれらの中からほんの一部を切り出して使用例とともに紹介します。

文字列[編集]

String[編集]

Stringとは、java.langパッケージに属するクラスです。 二重引用符で囲まれたリテラルは、全てこのクラスのインスタンスです。 また、Stringクラスは不変(imutable)なオブジェクトであるため、一度作成された文字列は変更することができません。 そのため、文字列を変更する場合は新しいStringクラスのインスタンスを作成する必要があります。

// 文字列の初期化
String str1 = "Hello World!";
String str2 = new String("Java Tutorial");

// 文字列の長さを取得
int length1 = str1.length();
int length2 = str2.length();

// 文字列の比較
boolean equal = str1.equals(str2);

// 文字列の連結
String str3 = str1 + " " + str2;

// 文字列の検索
int index1 = str1.indexOf("World");
int index2 = str2.indexOf("Java");

// 文字列の切り出し
String sub1 = str1.substring(0, 5);
String sub2 = str2.substring(0, 4);

// 文字列の変換
String upper1 = str1.toUpperCase();
String lower2 = str2.toLowerCase();


StringBuffer と StringBuilder[編集]

StringBufferとStringBuilderは、どちらもjava.langパッケージに属するクラスです。

Javaには、文字列を扱うための様々なクラスが用意されています。その中でも、StringBufferクラスとStringBuilderクラスは、文字列の変更や連結を行う際に優れたパフォーマンスを発揮します。

StringBufferクラスは、スレッドセーフな文字列バッファを提供します。このバッファは、可変長の文字列を格納するために使用され、そのサイズは自動的に拡張されます。StringBufferクラスのメソッドは、複数のスレッドから同時に呼び出されても安全に動作するように設計されています。

一方、StringBuilderクラスは、スレッドセーフではない文字列バッファを提供します。そのため、単一のスレッドでのみ使用することを前提としています。StringBuilderクラスは、StringBufferクラスと同様に可変長の文字列を格納するために使用されますが、単一のスレッドでの使用に特化しているため、パフォーマンスがより高速です。

StringBufferクラスとStringBuilderクラスは、共通のメソッドを多く持っています。例えば、append()メソッドを使用することで、文字列を末尾に連結することができます。insert()メソッドを使用することで、任意の位置に文字列を挿入することができます。また、reverse()メソッドを使用することで、文字列を逆順にすることができます。

以下は、StringBufferクラスとStringBuilderクラスの基本的な使い方の例です。 ここでは、文字列を逆順にするメソッドを使用して、文字列を逆順にしています。

public class StringBufferExample {
   public static void main(String[] args) {

      // using StringBuffer
      StringBuffer sbf = new StringBuffer("Hello");
      System.out.println("Original string: " + sbf);
      sbf.reverse();
      System.out.println("Reversed string: " + sbf);

      // using StringBuilder
      StringBuilder sbd = new StringBuilder("Hello");
      System.out.println("\nOriginal string: " + sbd);
      sbd.reverse();
      System.out.println("Reversed string: " + sbd);
   }
}

注意:StringBufferとStringBuilderは両方とも可変(mutable)な、文字列を操作するクラスです。StringBufferは、スレッドセーフなクラスであり、StringBuilderはスレッドセーフではありません。通常のシングルスレッドのJavaプログラムでは、StringBuilderの使用が推奨されます。

日付・時間[編集]

Date[編集]

Dateは、java.langパッケージに属するクラスです。 このクラスは、年月日と時分秒、そしてミリ秒を保持します。 ただし、うるう秒を追跡できない可能性がある[注 1]のと、世界協定時を反映することを意図していること、また月が1から12ではなく0から11までということがあり、実際に日付を扱うためには少し不便でした。 また、このクラスはJava 1.1までは日付を足したり引いたりすることが可能でしたが、Java 1.2からは非推奨となっています。

Calendar[編集]

Calendarは、java.langパッケージに属するクラスです。 このクラスは、特定の暦の実装が子クラスで提供されることを期待する抽象クラスです。 現在のCalendarを取得するためには、Calendar.getInstance()を使用します。

コレクション[編集]

Javaのコレクション(Collection)とは、オブジェクトを格納するためのデータ構造です。 Javaの標準ライブラリで提供されるJava Collection Frameworkは、これらのコレクションを利用するためのフレームワークであり、java.util.Collectionインタフェースを中心に構成されています。

java.util.Collectionインタフェースは、リスト(List)、セット(Set)、マップ(Map)などのコレクションクラスの共通の操作を定義しています。 Java Collection Frameworkでは、これらのコレクションクラスがCollectionインタフェースを実装することで、多くのメソッドや機能を共通化しています。

例えば、Collectionインタフェースにはsize()メソッドが含まれており、全てのコレクションクラスで利用できます。 また、isEmpty()メソッドやcontains()メソッド、add()メソッド、remove()メソッドなども含まれており、これらのメソッドはコレクションの種類に関わらず共通して利用することができます。

Java Collection Frameworkは、コレクションクラスに共通の機能を提供することで、コレクションの操作を簡単にし、コードの再利用性を高めることを目的としています。 また、一度学習すれば、複数のコレクションクラスを使用することができるため、効率的で柔軟なプログラミングを可能にします。

コレクションの種類[編集]

Java Collection Framework には、以下のような様々な種類のコレクションがあります。

Collection[編集]

Collectionインタフェースは、オブジェクトのコレクション(集合)を表すための基本的なメソッドを定義しています[注 2]Iteratorインタフェースの拡張インタフェースであり、SetListなどのコレクションの規約を定めています。また、Java 8からはdefaultメソッドとして、ストリームの処理を行うためのメソッドも提供しています。

List[編集]

順序付きの要素を格納するリストです。リストには重複する要素を含めることができます。代表的な実装として、ArrayList や LinkedList があります。

Set[編集]

重複する要素を許さない、順序を保持しないコレクションです。代表的な実装として、HashSet や TreeSet があります。

Map[編集]

キーと値のペアを格納するコレクションです。キーは重複することができませんが、値は重複することができます。代表的な実装として、HashMap や TreeMap があります。

コレクションの操作[編集]

Java Collection Framework では、以下のようなコレクションの操作が可能です。

要素の追加[編集]

コレクションに要素を追加するためには、以下のようにします。

List<String> list = new ArrayList<>();
list.add("apple");
list.add("banana");
Set<Integer> set = new HashSet<>();
set.add(1);
set.add(2);

要素の取り出し[編集]

コレクションから要素を取り出すためには、以下のようにします。

List<String> list = new ArrayList<>(); // ArrayList型のlist変数を宣言
list.add("apple"); // list変数に"apple"を追加する
list.add("banana"); // list変数に"banana"を追加する
// Java 5の拡張for文でlistの中身を全て出力する
for (var str : list) {
    System.out.println(str);
}

Set<Integer> set = new HashSet<>(); // HashSet型のset変数を宣言
set.add(1); // set変数に1を追加する
set.add(2); // set変数に2を追加する
// Java 5の拡張for文でsetの中身を全て出力する
for (var num : set) {
    System.out.println(num);
}

このコードは、JavaでListとSetの生成方法、要素の追加方法、そして拡張for文を使ってリストやセットの中身を全て出力する方法を示しています。

要素の削除[編集]

コレクションから要素を削除するためには、以下のようにします。

// Listを宣言し、配列リテラルで初期化する
List<String> list = new ArrayList<>(Arrays.asList("apple", "banana"));
// listから"apple"を削除する
list.remove("apple");

// Setを宣言し、配列リテラルで初期化する 
Set<Integer> set = new HashSet<>(Arrays.asList(1, 2));
// setから1を削除する
set.remove(1);

上記のコードでは、Arrays.asList()メソッドを使用して、配列リテラルを使ってListとSetを初期化しています。 また、Listのremove()メソッド、Setのremove()メソッドを使って、要素を削除しています。

コレクションのサイズの取得[編集]

コレクションの要素数を取得するためには、以下のようにします。

// List<String>型のlistを作成し、要素を"apple"と"banana"に追加する
List<String> list = new ArrayList<>(Arrays.asList("apple", "banana"));

// Listのサイズを取得して、int型の変数sizeに代入する
int size = list.size();

// Set<Integer>型のsetを作成し、要素として1と2を追加する
Set<Integer> set = new HashSet<>(Arrays.asList(1, 2));

// Setのサイズを取得して、int型の変数sizeに代入する
size = set.size();

Java5のジェネリック[編集]

Java5のジェネリックは、コレクションクラスやメソッドに型パラメータを追加することで、型安全性を向上させます。つまり、ミスがあった場合コンパイル時にエラーを出してくれるため、実行時に発生するエラーを防止することができます。ジェネリックを使うことで、コレクションに格納するデータの型を指定することができます。例えば、

List<String> list = new ArrayList<String>();

とすることで、Listに格納するデータがString型であることを宣言しています。また、ジェネリックが使われているコードは、可読性が向上し、バグを見つけるためのデバッグが容易になります。

コレクションファクトリーメソッド[編集]

Java 9からは、新しい「コレクションファクトリーメソッド」と呼ばれる機能が追加されました。これらのメソッドを使用することで、より簡潔で効率的なコードを書くことができます。

コレクションファクトリーメソッドには、以下のようなものがあります。

  • List.of()
  • Set.of()
  • Map.of()
  • Map.ofEntries()

これらのメソッドは、それぞれ指定された要素を持つList、Set、Mapを返します。これらのメソッドは、不変なコレクションを生成することができます。これにより、代入後に変更されないコレクションを作成することができます。 以下に使用例を示します。

List<String> list = List.of("apple", "banana", "orange");
Set<Integer> set = Set.of(1, 2, 3, 4, 5);
Map<String, Integer> map = Map.of("apple", 100, "banana", 200, "orange", 150);
Map<String, Integer> map2 = Map.ofEntries(
  new AbstractMap.SimpleEntry<>("apple", 100),
  new AbstractMap.SimpleEntry<>("banana", 200),
  new AbstractMap.SimpleEntry<>("orange", 150)
);

これらのメソッドを使用することで、コレクションを簡潔かつ効率的に生成することができます。また、この機能を使用することで、生成されたコレクションの要素を変更することができなくなるため、問題を回避することができます。

コレクションフレームワークの変更履歴[編集]

Javaコレクションで行われた主な変更点を新しい順にご紹介します:

Java 16
Listインタフェースに対して、要素を差し替えるメソッドであるreplaceAll(UnaryOperator)のパフォーマンスが大幅に向上。
Java 11
Collectionインターフェイスに、toArray(IntFunction<T[]> generator)という新しいデフォルトメソッドを追加。このメソッドは、このコレクションのすべての要素を含む配列を返し、提供されたジェネレーター関数を使用して返された配列を割り当てます。
Java 8
コレクションを扱うための関数型プログラミングを提供するStream APIを導入。
Collectionインターフェイスに、forEach、removeIf、spliteratorのデフォルトメソッドを追加。
Spliteratorインターフェイスを追加し、ストリーミング方式でコレクションを反復処理する方法を提供。
Java 7
Listインタフェースのスレッドセーフな実装であるCopyOnWriteArrayListクラスを追加。
Set インターフェースのスレッドセーフな実装である CopyOnWriteArraySet クラスを追加。
Map インターフェースのコンカレント実装である ConcurrentSkipListMap クラスを追加。
Setインタフェースの並行処理実装であるConcurrentSkipListSetクラスを追加。
Java 6
Set インターフェースのソート実装である TreeSet クラスを追加。
Map インターフェースのソート実装である TreeMap クラスを追加。
Set インタフェースのリンクされた実装である LinkedHashSet クラスを追加。
Mapインタフェースのリンク実装であるLinkedHashMapクラスを追加。
Java 5
コレクションを扱うための静的ユーティリティメソッドを提供する Collections クラスを追加。
Arraysクラスが追加されました。
List インターフェースの同期実装である Vector クラスを追加。
Mapインタフェースの同期実装であるHashtableクラスを追加。
LIFOスタックデータ構造であるStackクラスを追加。
プライオリティキューデータ構造であるPriorityQueueクラスを追加。
二重リンクリストデータ構造である LinkedList クラスを追加。
Listインタフェースの配列ベースの実装であるArrayListクラスを追加。
ハッシュテーブルを使用する Set インタフェースの実装である HashSet クラスを追加。
ハッシュテーブルを使用する Map インターフェースの実装である HashMap クラスを追加。


まとめ[編集]

Java Collection Framework は、Java でコレクションを扱うための強力な API です。List、Set、Map などのコレクションを使うことで、効率的にデータを格納し、操作することができます。また、API の豊富な機能を活用することで、コレクションを柔軟に操作することができます。

注釈[編集]

  1. ^ 実装依存
  2. ^ 有効な要素数は、0から2147483647個