I'd like someone to suggest a better way to create this pattern in Java which I'm sure is possible:
*********
* *
* *
* *
* *
* *
* *
* *
*********
I'm working my way through a new Java book and am examining string patterns.
public static void drawRectangle() {
// y axis
for( int y = 0; y <= 8; y++ )
{
if( y == 0 || y == 8 )
{
System.out.print( "*********\n" );
if( y == 8 )
{
// Leave loop
break;
}
}
// x axis
for( int x = 0; x <= 8; x++ )
{
if( x == 0 || x == 8 )
{
System.out.print( "*" );
if( x == 8 )
{
System.out.println();
}
}
else
{
System.out.print( " " );
}
}
}
}
Off the top of my head, I'd say that I could replace the values in the loops with constants to work towards. For example:
final static int END_POINT = 8;
Any thoughts?
3 Answers 3
It's ok for a first iteration.
- But your 2nd iteration should be
drawRectangle(int width, int height)
. That will force you to not hard-code your numbers. - Your 3rd iteration should be noticing that your rectangle only has 2 different rows (one row fills up the width with * and the other only has * in the beginning and end). You might want to make a method
drawHorizontal
to draw the top and bottom anddrawEnds
to draw the sides. For example
void drawHorizontal(int width) {
for (int i=0 ; i<width ; i++) {
System.out.print("*"); /* notice I'm using print() not println() */
}
System.out.println(""); /* notice I'm using println() */
}
void drawEnds(int width) {
System.out.print("*");
for (int i=1 ; i<width-1 ; i++) {
System.out.print(" ");
}
System.out.println("*");
}
-
\$\begingroup\$ Just for your information, I put together a fast speed test. Creating a string and outputting the whole string instead of printing single characters is a lot faster. Now that I think about it, iteration 4 should most likely return complete strings anyway. \$\endgroup\$Bobby– Bobby2013年09月17日 10:04:25 +00:00Commented Sep 17, 2013 at 10:04
-
\$\begingroup\$ @Bobby, yes but I wasn't sure if I should tell the OP about StringBuilder at this point. \$\endgroup\$Apprentice Queue– Apprentice Queue2013年09月17日 15:43:39 +00:00Commented Sep 17, 2013 at 15:43
-
\$\begingroup\$ I think a fourth or even fifth iteration with changes up to "I'd do it like this in the end" would be a very good addition and shouldn't be too hard to understand. \$\endgroup\$Bobby– Bobby2013年09月17日 16:19:46 +00:00Commented Sep 17, 2013 at 16:19
Interface suggestions
Anything that can be parameterized instead of hard-coded should be. I would pass the dimensions to the Rectangle
constructor. Then I would create a draw(PrintStream out)
method. In other words, the rectangle knows how to draw itself to a PrintStream
of your choice, whether it's System.out
or some other output destination.
Loop Simplification
You can simplify your code by letting Arrays.fill()
do the boring looping work to populate some buffers. Then, you only need one for
-loop to iterate over the rows. A bonus is that you take advantage of the fact that many of the lines to be printed are identical to each other.
Solution
import java.io.PrintStream;
import java.util.Arrays;
public class Rectangle {
private int rows, cols;
public Rectangle(int rows, int cols) {
this.rows = rows;
this.cols = cols;
}
public void draw(PrintStream out) {
char[] buf = new char[cols];
Arrays.fill(buf, '*');
String cap = new String(buf);
Arrays.fill(buf, 1, cols - 1, ' ');
String body = new String(buf);
out.println(cap);
for (int i = rows - 2; i >= 0; i--) {
out.println(body);
}
out.println(cap);
}
public static void main(String[] args) {
(new Rectangle(8, 8)).draw(System.out);
}
}
Alternative way to make Rectangle.
public class myclass {
// Input the size of the Rectangle.
static int hight = 8;
static int width = 8;
public static void main(String[] args) {
line(width);
for (int m = 0; m < hight - 2; m++) {
starWithSpace();
System.out.println();
}
line(width);
}
public static void space() {
System.out.print(" ");
}
public static void printStar() {
System.out.print("*");
}
public static void starWithSpace() {
printStar();
for (int i = 0; i <= hight - 2; i++) {
space();
}
printStar();
}
public static void line(int width) {
for (int header = 0; header <= width; header++) {
printStar();
}
System.out.println("");
}
}
-
7\$\begingroup\$ don't just post plain code,practice to give some explanation. \$\endgroup\$Gnanz– Gnanz2013年09月17日 13:52:22 +00:00Commented Sep 17, 2013 at 13:52
-
1\$\begingroup\$ Note, this answer is locked, and undeleted: it is significant as it provides context for a faq meta question: Should code block(s) as answers always require an explanation? \$\endgroup\$rolfl– rolfl2018年05月04日 01:12:09 +00:00Commented May 4, 2018 at 1:12
StringBuilder
. This is for performance reasons, so it is actually not very important for your problem. \$\endgroup\$