Created
December 29, 2011 12:12
-
-
Save torazuka/1533795 to your computer and use it in GitHub Desktop.
鈍器本の自前vector(double用)Java版
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package study.donki; | |
/** | |
* 『ストラウストラップのプログラミング入門』の自前vector(※ただしdouble型に限る)をJavaで書き換えてみる | |
* | |
*/ | |
public class VectorModoki implements Cloneable { | |
private int sz; // 要素数(明示的に値を代入した要素の数) | |
private double[] elem; // 要素 | |
private int space; // 要素数+空きスロット数。elem.lengthとイコール。 | |
public VectorModoki() { | |
sz = 0; | |
space = 0; | |
elem = null; | |
} | |
public VectorModoki(int s) { | |
sz = s; | |
elem = new double[s]; | |
space = s; | |
for (int i = 0; i < sz; i++) { | |
elem[i] = 0.0; | |
} | |
} | |
public VectorModoki(final VectorModoki arg) { | |
sz = arg.sz; | |
elem = new double[arg.sz]; | |
for (int i = 0; i < arg.sz; i++) { | |
elem[i] = arg.elem[i]; | |
} | |
} | |
/** | |
* VectorModokiオブジェクトのディープコピーを行う。 operator=のオーバーライドもどき。(?) | |
* | |
* @see java.lang.Object#clone() | |
*/ | |
@Override | |
public Object clone() { | |
try { | |
// TODO: szまでの要素をコピーし、後ろの余分なspaceはコピーしたくない。 | |
return super.clone(); | |
} catch (CloneNotSupportedException e) { | |
// ユーザコード側でcatchするのがめんどいので握りつぶす。ひしだまさんリスペクト。 | |
// c.f. http://www.ne.jp/asahi/hishidama/home/tech/java/clone.html | |
throw new InternalError(e.toString()); | |
} | |
} | |
/** | |
* インデックスアクセスのために、getメソッドを提供する。VectorModokiは[]オペレータによるアクセスを提供できないため。 | |
* | |
* @param index | |
* @return | |
*/ | |
public double get(int index) { | |
// getの上限がelem.lengthでなくszなのは、明示的に値を代入済みの要素までを取得可能な要素とみなすため。 | |
if (index < 0 || sz < index) { | |
throw new ArrayIndexOutOfBoundsException(); // gomen... | |
} | |
return elem[index]; | |
} | |
public int size() { | |
return sz; | |
} | |
public final int capacity() { | |
return space; | |
} | |
public void resize(int newsize) { | |
// VectorModokiにnewsize個の要素を持たせる | |
reserve(newsize); | |
for (int i = sz; i < newsize; ++i) { | |
elem[i] = 0.0; // 新しい要素を初期化する | |
} | |
sz = newsize; | |
} | |
public void push_back(double d) { | |
if (space == 0) { // 最初は要素8つ分の領域を確保する | |
reserve(8); | |
} else if (sz == space) { | |
reserve(2 * space); | |
} | |
elem[sz] = d; // dを値あり要素の末尾として追加する | |
++sz; // サイズを増やす | |
} | |
public void reserve(int newalloc) { | |
if (newalloc <= space) { | |
return; | |
} | |
double[] p = new double[newalloc]; // 新しい領域を割り当てる | |
// 古い領域をコピーする。ただし、明示的に値を代入した要素までとする。 | |
for (int i = 0; i < sz; i++) { | |
p[i] = elem[i]; | |
} | |
// Javaにはdeleteがないので、古い領域の割り当て解除は省略 | |
elem = p; | |
assert equals(elem.length == newalloc); | |
space = newalloc; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment