import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Random;
/*
A) 複素数のシリアルオブジェクトを定義し、
値を設定/読み出すメソッド、
および絶対値を求めるメソッドを定義せよ
B) 10個一組の異なる複素数オブジェクトを2組生成し、
それぞれ2つの異なる出力ファイルに書き出すプログラムを作成。
C) 上記2つのファイルを読み出し所定のデータが戻っていることを
確認するためそれぞれの値と絶対値を表示しなさい。
D) さらに、夫々のファイルから1組ずつオブジェクトを取り出し夫々
掛算して、掛算結果と絶対値を求め表示するプログラムを作成せよ。
*/
/**
* 複素数型.immutable.
* なぜなら複素数は値なので,値の価は他の何物にも変わらない.
*/
public class ComplexTest {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Complex[] complexes1 = makeRandomComplex(10);
Complex[] complexes2 = makeRandomComplex(10);
// complexes1と complexes2を書き出す
writeObjectToFile("complexes1", complexes1);
writeObjectToFile("complexes2", complexes2);
// complexes1と complexes2を無かったことにする
complexes1 = complexes2 = null;
// complexes1と complexes2を読み出す
complexes1 = (Complex[]) readObjectFromFile("complexes1");
complexes2 = (Complex[]) readObjectFromFile("complexes2");
// 読み出したcomplexes1と complexes2を表示する
System.out.println(Arrays.toString(complexes1));
System.out.println(Arrays.toString(complexes2));
// complexes1と complexes2からそれぞれ一組ずつ読み出して,計算する
for (int p1 = 0; p1 < complexes1.length; p1++) {
for (int p2 = 0; p2 < complexes2.length; p2++) {
Complex c1 = complexes1[p1], c2 = complexes2[p2];
Complex multiplied = c1.mul(c2);
System.out.println(c1 + " * " + c2 + "=" + multiplied + " [remove =" + multiplied.getRemove() + "]");
}
}
}
private static final Complex[] makeRandomComplex(final int nCount) {
Random r = new Random();
Complex[] complexes = new Complex[nCount];
for (int i = 0; i < nCount; i++) {
complexes[i] = new Complex(r.nextDouble() * 100 - r.nextDouble() * 100, r.nextDouble() * 100 - r.nextDouble() * 100);
}
return complexes;
}
public static final void writeObjectToFile(final String file_name, final Object o) throws IOException {
FileOutputStream fos = new FileOutputStream(new File (new File("."), file_name));
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(o);
oos.flush();
oos.close();
fos.close();
}
public static final Object readObjectFromFile(final String file_name) throws IOException, ClassNotFoundException {
FileInputStream fis = new FileInputStream(new File(new File("."), file_name));
ObjectInputStream ois = new ObjectInputStream(fis);
return ois.readObject();
}
}
class Complex implements Serializable {
public static final double DOUBLE_EPSILON = Double.MIN_VALUE * 1000; // コレより絶対値が小さい値を0とみなす
private static final long serialVersionUID = -6848384132789177772L;
private final double _r, _i;
public Complex(final double real, final double imaginary) {
_r = real;
_i = imaginary;
}
public final Complex set(final double real, final double imaginary) {
return new Complex(real, imaginary);
}
public final double getReal() {
return _r;
}
public final double getImaginary() {
return _i;
}
public final double getRemove() {
return Math.sqrt(_r * _r + _i * _i);
}
public final Complex add(final Complex rhs) {
return new Complex(_r + rhs._r, _i + rhs._i);
}
public final Complex mul(final Complex rhs) {
// (a+bi)*(c+di)=ac-bd+(ad+bc)i
return new Complex(_r * rhs._r - _i * rhs._i, _r * rhs._i + _i * rhs._r);
}
@Override
public String toString() {
double abs_real = Math.abs(_r);
double abs_img = Math.abs(_i);
boolean has_real = abs_real >= DOUBLE_EPSILON;
boolean has_imaginary = abs_img >= DOUBLE_EPSILON;
if (!has_real && !has_imaginary) {
return "0";
} else {
StringBuilder sb = new StringBuilder();
if (has_real && has_imaginary) {
sb .append('(')
.append(_r)
.append(Math.signum(_i) < 0 ? '-' : '+')
.append(abs_img)
.append('i')
.append(')');
} else if (has_real && !has_imaginary) {
sb.append(_r);
} else if (!has_real && has_imaginary) {
sb .append(Math.signum(_i) < 0 ? '-' : '+')
.append(abs_img)
.append('i');
}
return sb.toString();
}
}
}