ジェネリック
ジェネリックとは何ですか
ジェネリックスは、クラス、インターフェイス、またはメソッドを定義するときに 1 つ以上の型パラメーターを使用できるようにするプログラミング言語で使用される概念です。ジェネリックスを使用すると、さまざまな種類のデータを処理するジェネリック コードを作成でき、コードの再利用性と型の安全性が向上します。
ジェネリック医薬品のメリット
1. 型安全性: ジェネリックスを使用すると、実行時のエラーではなく、コンパイル時に型エラーを検出できます。
2. コードの再利用: 共通のコードを作成し、異なるタイプ間で共有できるため、冗長なコードの作成が削減されます。
3. パフォーマンスの最適化: ジェネリック コードはタイプ セーフであるため、コンパイラーは特定のタイプに対して最適化してコードのパフォーマンスを向上させることができます。
たとえば、Java では、ジェネリックを使用して汎用の List コンテナを定義し、List をインスタンス化するときに格納する要素のタイプを指定できます。これにより、データ型ごとに個別のコンテナー クラスを作成しなくても、同じ List クラスをさまざまなシナリオで使用できるようになります。このアプローチにより、コードの柔軟性と再利用性が向上します。
汎用スタック
汎用スタックとは何ですか
ジェネリック スタックは、ジェネリックの概念を使用して実装されたデータ構造であり、さまざまなタイプの要素を格納できます。汎用スタックでは、type パラメーターを指定して格納する要素のタイプを定義し、スタック上でプッシュやポップなどの一般的な操作を実行できます。
一般的なスタック定義では通常、クラスまたはインターフェイスを使用し、山かっこ (<>) を使用して型パラメータを指定します。
汎用スタックの利点
1. 型変換エラーの回避: ジェネリックスを使用すると、スタック使用時に頻繁に型変換が発生する問題を回避できます。ジェネリック スタックは、コンパイル時に型チェックを実行して、指定された型の要素のみを格納できるようにするため、コードの型安全性が向上します。
2. コードの可読性と保守性の向上: 汎用スタックはさまざまなタイプのデータを保管および操作できるため、コードがより一般的で可読性が高くなります。データ型ごとに異なるスタック クラスを作成する必要がないため、冗長なコード記述が削減され、コードの保守性が向上します。
3. コードの再利用: 汎用スタックを定義すると、タイプごとにスタックを再実装することなく、同じスタックを使用してさまざまなシナリオでロジックを実装できます。これにより、コードの重複が減り、コードの再利用性とスケーラビリティが向上します。
4. パフォーマンスの最適化: 汎用スタックはコンパイル時に保存される型を決定するため、コンパイラーはマシン コードを生成するときにコードを最適化できます。これにより、実行時の型チェックと変換が必要なくなるため、実行時のパフォーマンスがより効率的になります。
5. データ型の制限: ジェネリックスを使用すると、スタックに格納されるデータ型を制限できます。これは、指定されたタイプの要素のみを保存できることを意味し、より厳密なデータ制約が提供され、潜在的なエラーや例外が減少します。
全体として、汎用スタックは、コードの実装を簡素化し、コードの可読性、保守性、パフォーマンスを向上させる、より柔軟でタイプセーフで再利用可能なデータ構造を提供します。
コード
配列があり、プッシュとポップの操作を継続的に実現する必要があるとします。そのため、プッシュ シーケンスは 1,2、ポップは 2,1 になります。図: まず、配列を定義し、初期値を与え
ます
。
public static int[] data = new int[5];
配列の最後の位置を決定するには、ポインタのような変数が必要です。
public static int size = 0;
次に、スタック メソッドに書き込みます。
public void push(int i){
data[size ++] = i;
if (size == data.length){
data = Arrays.copyOf(data,data.length * 2);
}
}
1 を渡すとすると、i = 1 になります。size = 0、size++ なので、順序は data[0] = 1、size+1 = 1 になります。サイズが配列の長さと等しい場合、スタックをプッシュし続けると配列が範囲外になり、拡張する必要があります。
次にpopメソッドです。
public int pop(){
if(size == 0){
throw new RuntimeException("栈为空");
}
int old = data[size-1];
size = size - 1;
return old;
}
size はスタックにプッシュされる次の座標を表すため、size には要素がなく、size-1 はスタックにプッシュされる要素を表すことに注意してください。
完全なコードは次のとおりです。
public class DemoStack {
public static int[] data = new int[5];
public static int size = 0;
/**
*
* @param i
*/
public void push(int i){
data[size ++] = i;
if (size == data.length){
data = Arrays.copyOf(data,data.length * 2);
}
}
public int pop(){
if(size == 0){
throw new RuntimeException("栈为空");
}
int old = data[size-1];
size = size - 1;
return old;
}
}
汎用スタックとは、スタックにプッシュしたいのは上記のコードの int 型だけでなく、他の型も含むことを意味します。したがって、 in を E に変更するだけです
public class EDemoStack<E> {
public Object[] data = new Object[5];
public int size = 0;
/**
*
* @param i
*/
public void push(E i){
data[size ++] = i;
if (size == data.length){
data = Arrays.copyOf(data,data.length * 2);
}
}
public E pop(){
if(size == 0){
throw new RuntimeException("栈为空");
}
E old = (E) data[size-1];
size = size - 1;
return old;
}
}
これでコードは完成です。コードでテストを実行してみましょう。
public static void main(String[] args) {
EDemoStack<String> stack = new EDemoStack<>();
stack.push("123");
stack.push("喜羊羊");
stack.push("aaa");
System.out.println(stack.pop());
System.out.println(stack.pop());
System.out.println(stack.pop());
}
出力結果: