学生向けプログラミング入門 | 無料

学生向けにプログラミングを無料で解説。Java、C++、Ruby、PHP、データベース、Ruby on Rails, Python, Django

Javaプログラミング入門その22 クラス分けした表作成プログラム

>>この記事には書き直した新しいページがあります。<<


<<前  [TOP]  次>>


メモ帳を開いて次の6つのプログラムを作ってみましょう。


【Size.java】

public class Size {

	public static int count( String str ) {

		int count = 0;
		char[] a = str.toCharArray();
		for( int i=0; i<str.length(); i++ ) {
			if( Character.UnicodeBlock.of( a[i] ).equals( Character.UnicodeBlock.BASIC_LATIN ) ) {

				count++;
			}

			else {

				count+=2;
			}
		}
		return count;
	}
}

【Yose.java】

public class Yose {


	public static final int NONE = 0;
	public static final int LEFT = 1;
	public static final int RIGHT = 2;
	public static final int CENTER = 3;

	public String text;
	public int size;
	public int flag;
	
	public Yose() {
		text = "";
		size = 0;
		flag = NONE;
	}
	public Yose( String s ) {
		text = s;
		size = s.length();
		flag = NONE;

	}

	public Yose( String s, int i ) {

		text = s;
		size = s.length();
		flag = i;
	}

	public void print() {
		int count = Size.count( text );
		if( flag == LEFT || flag == NONE ) {
			System.out.print( text );
			for( int i=count; i<size; i++ ) {
				System.out.print( " " );
			}
		}
		else if( flag == RIGHT ) {
			for( int i=count; i<size; i++ ) {
				System.out.print( " " );
			}
			System.out.print( text );
		}
		else if( flag == CENTER ) {
			int s = size - count;
			int s1, s2;
			
			if( (s % 2) == 0 ) {
				s1 = s2 = s/2;
			}
			else {
				s1 = s/2 +1; s2 = s/2;
			}
			for( int i=0; i<s1; i++ ) {
				System.out.print( " " );
			}
			System.out.print( text );

			for( int i=0; i<s2; i++ ) {
				System.out.print( " " );
			}
		}
	}
}

【Ookisa.java】

public class Ookisa {

	public Yose[] yose;
	public int height;
	public int maxSize;

	public Ookisa( Yose[] y ) {

		yose = y;
		height = y.length;
		maxSize = y[0].size;

		for( int j=1; j<y.length; j++ ) {

			if( maxSize < y[j].size ) {
			
				maxSize = y[j].size;
			}
		}

		for( int j=0; j<y.length; j++ ) {

			y[j].size = maxSize;
		}
	}
}

【Hyouji.java】

public class Hyouji {

	public Yose[] yose;

	public int width;
	
	public Hyouji( Yose[] c ) {
		yose = c;	
		width = c.length;
	}
	
	public Hyouji( Yose[] c, int flag ) {

		this( c );
		for( int i=0; i<width; i++ ) {

			if( c[i].flag == Yose.NONE ) {
				c[i].flag = flag;
			}
		}
	}

	public void print() {
		System.out.print( "|" );
	
		for( int i=0; i<width; i++ ) {
			yose[i].print();
			System.out.print( "|" );
		}
		System.out.println( "" );
	}
}

【Hyou11.java】

public class Hyou11 {
	public Hyouji[] hyouji;
	public Ookisa[] ookisa;
	public int width;
	public int height;
	
	public Hyou11( Hyouji[] h ) {
		hyouji = h;
		width = h[0].width;
		height = h.length;
		ookisa = new Ookisa[width];

		for( int i=0; i<width; i++ ) {
			Yose[] yose = new Yose[height];
			for( int j=0; j<height; j++ ) {
				yose[j] = hyouji[j].yose[i];
			}
			ookisa[i] = new Ookisa( yose );
		}
	}
	public Hyou11( Hyouji[] h, int flag ) {
		this( h );
		for( int i=0; i<width; i++ ) {
			for( int j=0; j<height; j++ ) {
				if( hyouji[j].yose[i].flag == Yose.NONE ) {
					hyouji[j].yose[i].flag = flag;
				}
			}
		}
	}
	public void print() {
		for( int j=0; j<height; j++ ) {
			hyouji[j].print();
		}
	}
}

【HyouTest.java】

public class HyouTest {

	public static void main( String[] args ) {

		Yose[] yose1 = { new Yose( "Hokkaidou" ), new Yose( "Okinawa" ), new Yose( "Kyuushuu" ), new Yose( "Honshuu" ) };

		 Yose[] yose2 = { new Yose( "Yamada" ), new Yose( "Suzuki" ), new Yose( "Takahashi" ), new Yose( "Itou" ) };

		 Yose[] yose3 = { new Yose( "Tarou" ), new Yose( "Jirou" ), new Yose( "Saburou" ), new Yose( "Shirou" ) };

		Yose[] yose4 = { new Yose( "飛行機" ), new Yose( "新幹線" ), new Yose( "フェリー" ), new Yose( "徒歩" ) };


		Hyouji[] hyouji = { new Hyouji( yose1 ), 
				new Hyouji( yose2 ), 
				new Hyouji( yose3 ),
				new Hyouji( yose4 ) 
				};

		Hyou11 hyou11 = new Hyou11( hyouji, Yose.CENTER );

		hyou11.print();
	}
}



「Size.java」は文字が英数字なら1をプラスし、それ以外なら2をプラスして文字列の大きさを求める処理をするメソッド(count)のあるクラスです。
countはstaticなので他のクラスで使用するときはインスタンスを作成する必要が無く、Size.count( 引数 )で呼び出すことができます。


「Yose.java」は、与えられたflagにより右寄せ、左寄せ、中央寄せに分けて処理をします。
与えられた文字列のサイズをSize.countメソッドを利用し調べます。


「Ookisa.java」は、このクラスのコンストラクタは与えられたインスタンスに対してその列ごとの文字列の最大の大きさを求め、このクラスのフィールド(maxSize)に代入します。
求めたmaxSizeをその列全部に代入します。
heigthはYoseの配列の数、つまりhyouji.lengthを表しています。
列の数(縦方向の数)です。
これはHyouTestから順にたどっていけば解ります。
y[0].sizeはYoseクラスのコンストラクタの中にあるsizeフィールドを指しています。


「Hyouji.java」はflagが渡されているときの処理と、そうでないときの処理の2つに分けたコンストラクタを用意しています。
与えられたインスタンスを表示するクラスです。
widthはYoseインスタンスの配列の数(yose.length)を表しています。
横方向の数です。


「Hyou11.java」について説明します。


ここで渡されているRowのインスタンスは配列インスタンスです。
この配列には、Yoseの配列インスタンスが格納されています。
HyouTestクラスでその作業は行われています。
次の記述を見てください。

for( int i=0; i<width; i++ ) {
    Yose[] yose = new Yose[height];
    for( int j=0; j<height; j++ ) {
        yose[j] = hyouji[j].yose[i];
    }
    ookisa[i] = new Ookisa( yose );
}

これは新しく用意したYoseの配列にyoseのインスタンスを格納し直し(今は、hyoujiクラスのインスタンスを受け取っているのでyoseインスタンスのみを格納し直す)、さらにもう一つの新しく用意したOokisaクラスのインスタンス配列に格納しています。
こうすることでOokisaクラスにもYoseクラスのインスタンスを渡すことができます。

for( int i=0; i<width; i++ ) {
    for( int j=0; j<height; j++ ) {
        if( hyouji[j].yose[i].flag == Yose.NONE ) {
            hyouji[j].yose[i].flag = flag;
        }
    }
}

もしyoseインスタンスにflagが渡されていなければ、hyouji.yoseのインスタンスに今回渡された引数flagを代入します。
ここでflagを代入すると、すべてがそのflagになります。
一つずつflagを決めたいときは、そのyoseインスタンスを生成するときに引数にflagを渡してやります。
そうすれば( hyouji[j].yose[i].flag == Yose.NONE )の条件に当てはまらず、flagは書き換えられません。


printメソッドでRowクラスのprintメソッドにインスタンスを渡し、呼び出しています。

hyouji[j].print();



「HyouTest.java」の処理の流れを順を追って見ていきましょう。


まずYoseクラスが呼び出され、値がそれぞれのインスタンスに代入されていきます。

Yose[] yose1 = { new Yose( "Hokkaidou" ), new Yose( "Okinawa" ), new Yose( "Kyuushuu" ), new Yose( "Honshuu" ) };

今回は次のコンストラクタが呼び出され値が代入されています。

public Yose( String s ) {
    text = s;
    size = s.length();
    flag = NONE;
}

textはHokkaidou,Okinawaなどが代入され、sizeはそれぞれ9、7、8、7で、flagは全部NONEになります。


次にHyoujiクラスが呼び出されて、値が代入されていきます。

Hyouji[] hyouji = { new Hyouji( yose1 ), new Hyouji( yose2 ), new Hyouji( yose3 ),new Hyouji( yose4 ) };

今回は次のコンストラクタが呼び出され値が代入されています。

public Hyouji( Yose[] c ) {
    yose = c; 
    width = c.length;
}

今回、widthは4です。

Hyou11 hyou11 = new Hyou11( hyouji, Yose.CENTER );

このクラスで作成したyoseインスタンス配列の入ったhyoujiインスタンス配列(hyouji)とYoseクラスのstatic定数フィールド(Yose.CENTER)を引数としてHyou11クラスのインスタンス(hyou11)をHyou11クラスに渡します。


Hyou11クラスでは今回は次のコンストラクタが呼び出されます。

public Hyou11( Hyouji[] h, int flag ) {
        this( h );
        for( int i=0; i<width; i++ ) {
            for( int j=0; j<height; j++ ) {
                if( hyouji[j].yose[i].flag == Yose.NONE ) {
                    hyouji[j].yose[i].flag = flag;
                }
            }
        }
}

ここでのthis( h );は次の部分を指します。

hyouji = h;
width = h[0].width;
height = h.length;
ookisa = new Ookisa[width];

for( int i=0; i<width; i++ ) {
    Yose[] yose = new Yose[height];
    for( int j=0; j<height; j++ ) {
        yose[j] = hyouji[j].yose[i];
    }
    ookisa[i] = new Ookisa( yose );
}

widthには先ほどのwidthが呼び出されて代入されています。
heightには、hyouji配列の数が代入されます。
これはwidthは表の横のブロックの数、heightは縦のブロックの数を表していることになります。


二重ループではOokisaクラスのインスタンス配列にYoseクラスのインスタンスを代入しOokisaクラスに渡します。


Ookisaクラスでは、一番多い文字数を調べそれを各Yoseクラスのインスタンスのsizeに代入しています。
他にもheight(yoseインスタンス配列の数)などを返します。


Hyou11クラスでは他にも、flagが無い場合の処理をしています。

for( int i=0; i<width; i++ ) {
        for( int j=0; j<height; j++ ) {
            if( hyouji[j].yose[i].flag == Yose.NONE ) {
                hyouji[j].yose[i].flag = flag;
            }
        }
}



前で求めたHyou11クラスのインスタンス(hyou11)をHyou11クラスのprintメソッドに渡します。

hyou11.print();



Hyou11クラスのprintメソッドでは、このクラスで求めたHyoujiクラスのインスタンスをHyoujiクラスのprintメソッドにfor文で渡します。

public void print() {
    for( int j=0; j<height; j++ ) {
        hyouji[j].print();
    }
}



Hyoujiクラスのprintメソッドでは、"|"の表示とこのクラスで求めたYoseクラスのインスタンスをYoseクラスのprintメソッドに渡しています。

public void print() {
    System.out.print( "|" );

    for( int i=0; i<width; i++ ) {
        yose[i].print();
        System.out.print( "|" );
    }
    System.out.println( "" );
}



Yoseクラスのprintメソッドでは、Sizeクラスのcountメソッド(static)を使ってtextの大きさをcountとして求めています。

int count = Size.count( text );

それを使い、flagに従ってtextを表示していきます。


出力結果です。
6つのプログラム「Size.java」「Yose.java」「Ookisa.java」「Hyouji.java」「Hyou11.java」「HyouTest.java」をすべてコンパイルして、「HyouTest.java」を実行します。


HyouTest.java実行結果
HyouTest.java実行結果


<<前  [TOP]  次>>