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

学生向けにプログラミングを解説。Java、C++、Ruby、PHP、データベース

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;
}

今回、withは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 );
}

withには先ほどのwithが呼び出されて代入されています。
heightには、hyouji配列の数が代入されます。
これは、withは表の横のブロックの数、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」を実行します。





<<前  [TOP]  次>>