Java - データ構造

こんにちは、未来のプログラマーたち!今日は、Javaのデータ構造の面白い世界に飛び込んでみましょう。あなたの近所の親切なコンピュータサイエンスの先生として、私はこの旅をステップバイステップで案内します。プログラミングが初めてであれば心配しないでください - 基礎から始めて少しずつ進めていきます。では、仮想のヘルメットをかぶり、知識の構築を始めましょう!

Java - Data Structures

データ構造の紹介

具体的なJavaのデータ構造に入る前に、データ構造とは何か、そしてなぜそれが重要なのかを理解しましょう。

図書館を整理する imagine してみてください。すべての本を一積みにするわけではありませんよね?もちろんありません!本を整理して、見つけやすく管理しやすいようにします。データ構造はプログラミングにおけるデータに対してまさに同じことを行います。

データ構造は、データを効率的にアクセスおよび修正できるように整理して保存する方法です。Javaには、それぞれに強みと用途があるいくつかの組み込みデータ構造があります。

Javaの組み込みデータ構造

では、Javaで最も一般的なデータ構造をいくつか見てみましょう。

列挙

列挙は、一つずつ番号を発行する切符 vending machine みたいなものです。Javaのインターフェースで、コレクション内の要素を一つずつアクセスすることができます。

以下に簡単な例を示します:

import java.util.*;

public class EnumerationExample {
public static void main(String args[]) {
Vector<String> dayNames = new Vector<>();
dayNames.add("月曜日");
dayNames.add("火曜日");
dayNames.add("水曜日");

Enumeration<String> days = dayNames.elements();

while (days.hasMoreElements()) {
System.out.println(days.nextElement());
}
}
}

この例では、VectorのdayNamesを作成し、列挙を使用してそれらを反復します。hasMoreElements()メソッドは次の要素があるかどうかをチェックし、nextElement()メソッドは次の要素を取得します。

ビット集合

ビット集合は、それぞれがオン(1)またはオフ(0)であるライトスイッチの行のようなものです。true/false値を効率的に保存する必要がある場合に便利です。

以下に例を示します:

import java.util.BitSet;

public class BitSetExample {
public static void main(String args[]) {
BitSet bits1 = new BitSet(16);
BitSet bits2 = new BitSet(16);

// ビットを設定
for(int i = 0; i < 16; i++) {
if((i % 2) == 0) bits1.set(i);
if((i % 5) != 0) bits2.set(i);
}

System.out.println("bits1の初期パターン: " + bits1);
System.out.println("bits2の初期パターン: " + bits2);

// ビットをAND
bits2.and(bits1);
System.out.println("bits2 AND bits1: " + bits2);
}
}

この例では、BitSetの作成、ビットの設定、ビット演算の実行を示しています。

ベクター

ベクターは、必要に応じて拡大または縮小できる魔法の配列のようなものです。ArrayListに似ていますが、スレッドセーフな同步が行われています。

以下にベクターの使用例を示します:

import java.util.*;

public class VectorExample {
public static void main(String args[]) {
Vector<Integer> vec = new Vector<>(3, 2);
System.out.println("初期サイズ: " + vec.size());
System.out.println("初期キャパシティ: " + vec.capacity());

vec.addElement(1);
vec.addElement(2);
vec.addElement(3);
vec.addElement(4);
System.out.println("4つの追加後のキャパシティ: " + vec.capacity());

vec.addElement(5);
System.out.println("現在のキャパシティ: " + vec.capacity());

System.out.println("最初の要素: " + vec.firstElement());
System.out.println("最後の要素: " + vec.lastElement());
}
}

この例では、ベクターの作成、要素の追加、サイズとキャパシティの確認を示しています。

スタック

スタックは、皿の山のように、上からしか追加または削除できないものです。後入先出(LIFO)の原則に従います。

以下にスタックの使用例を示します:

import java.util.*;

public class StackExample {
public static void main(String args[]) {
Stack<String> stack = new Stack<>();
stack.push("Bottom");
stack.push("Middle");
stack.push("Top");

System.out.println("Stack: " + stack);
System.out.println("Popped: " + stack.pop());
System.out.println("Stack after pop: " + stack);
System.out.println("Peek: " + stack.peek());
System.out.println("Stack after peek: " + stack);
}
}

この例では、要素をスタックにプッシュ、ポップ、ピークする方法を示しています。

辞書

辞書は、キーと値のデータ構造を表す抽象クラスです。実際の辞書のように、各単語(キー)に定義(値)があります。

辞書は抽象であり直接インスタンス化できませんが、そのサブクラスであるHashtableが一般的に使用されます:

import java.util.*;

public class DictionaryExample {
public static void main(String args[]) {
Dictionary<String, String> dict = new Hashtable<>();

dict.put("Apple", "果物");
dict.put("Java", "プログラミング言語");
dict.put("Computer", "電子機器");

System.out.println("Dictionary: " + dict);
System.out.println("Key 'Java'の値: " + dict.get("Java"));

System.out.println("キー: ");
for (Enumeration<String> keys = dict.keys(); keys.hasMoreElements();) {
System.out.println(keys.nextElement());
}
}
}

この例では、辞書(Hashtableを通じて)を使用してキーと値のペアを保存および检索する方法を示しています。

ハッシュテーブル

ハッシュテーブルは、非常に効率的な書類保管庫のようなものです。キーと値のペアを保存し、キーに基づいて値を迅速に检索できます。

以下にハッシュテーブルの使用例を示します:

import java.util.*;

public class HashtableExample {
public static void main(String args[]) {
Hashtable<String, Integer> numbers = new Hashtable<>();
numbers.put("one", 1);
numbers.put("two", 2);
numbers.put("three", 3);

System.out.println("Hashtable: " + numbers);
System.out.println("Value of 'two': " + numbers.get("two"));
System.out.println("Is 'four' a key? " + numbers.containsKey("four"));
System.out.println("Is 3 a value? " + numbers.containsValue(3));

numbers.remove("two");
System.out.println("Removing 'two' after Hashtable: " + numbers);
}
}

この例では、キーと値のペアをハッシュテーブルに追加、値の检索、キーと値の存在確認、エントリの削除を示しています。

プロパティ

プロパティは、文字列のキーと値のペアを保存する特別な種類のハッシュテーブルです。設定設定に使用されることが多いです。

以下にプロパティの使用例を示します:

import java.util.*;

public class PropertiesExample {
public static void main(String args[]) {
Properties capitals = new Properties();
capitals.put("USA", "Washington D.C.");
capitals.put("France", "Paris");
capitals.put("Japan", "Tokyo");

System.out.println("Properties: " + capitals);
System.out.println("Capital of France: " + capitals.getProperty("France"));

// デフォルト値を設定
System.out.println("Capital of Spain: " + capitals.getProperty("Spain", "Not Found"));

capitals.list(System.out);
}
}

この例では、プロパティを使用して文字列のキーと値のペアを保存および检索する方法を示しています。

結論

おめでとうございます!Javaのデータ構造の世界への最初の一歩を踏み出しました。これらの構造はそれぞれ独自の特性と用途を持っています。プログラミングの旅を続ける中で、特定のニーズに応じて異なる構造を使用する必要があるでしょう。

適切なデータ構造を選ぶことは、プログラムの効率に大きな影響を与えることがあります。工具を選ぶのと同じで、ハンマーは釘に最適ですが、ネジには適していません!

これらの構造を練習し、自分のプロジェクトで使用してみてください。実験を恐れずに!お楽しみください!

Credits: Image by storyset