# Making a rectangular-shaped pattern

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?

• When doing a lot of string concatenations, you should instead use a StringBuilder. This is for performance reasons, so it is actually not very important for your problem. – toto2 Sep 17 '13 at 1:46
• it may be for this particular problem but I'm sure I'll come across it again at some point. Thanks – Katana24 Sep 17 '13 at 9:19

It's ok for a first iteration.

1. But your 2nd iteration should be drawRectangle(int width, int height). That will force you to not hard-code your numbers.
2. 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 and drawEnds 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("*");
}

• 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. – Bobby Sep 17 '13 at 10:04
• @Bobby, yes but I wasn't sure if I should tell the OP about StringBuilder at this point. – Apprentice Queue Sep 17 '13 at 15:43
• 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. – Bobby Sep 17 '13 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) {