Printing a diamond-shaped figure How can I optimize this code to have fewer loops and return values for unit testing?

 public class Diamond {

public void DiamondShape(int num) {

   for(int ucount=num;ucount&gt;0;ucount--) {
//Loop to print blank space
    for(int count_sp=1;count_sp&lt;ucount;count_sp++)
        System.out.printf(" ");
//Loop to print *
    for(int count_ast=num;count_ast&gt;=ucount;count_ast--)
        System.out.printf("* ");
    System.out.println();
   }

//Loop for lower half
  for(int lcount=1;lcount&lt;num;lcount++) {
    //Loop to print blank space
    for(int count_sp=0;count_sp&lt;lcount;count_sp++)
            System.out.printf(" ");
    //Loop to print *
        for(int count_ast=num-1;count_ast&gt;=lcount;count_ast--)
            System.out.printf("* ");
    System.out.println();
    }
  } 
}


Output when num = 3:


   *
  * *
 * * *
  * *
   *



This is how the output should be. num indicates the star in center line.
First of all: Use a StringBuilder instead of System.out.println so you can easily compare the result of your method with an expected output.

Your test could look like: (I renamed you method to draw and moved the size to the instance.)

@Test
public void test4()
{
    StringBuilder expected = new StringBuilder();
    expected.append( "   * \n" );
    expected.append( "  * * \n" );
    expected.append( " * * * \n" );
    expected.append( "* * * * \n" );
    expected.append( " * * * \n" );
    expected.append( "  * * \n" );
    expected.append( "   * \n" );
    assertEquals( expected.toString(), new Diamond( 4 ).draw() );
}


After you have all your tests (I have just created some for 0-4) you can try to extract some methods with duplicate code.

public class Diamond
{
    private int size;

    public Diamond( int size )
    {
        this.size = size;
    }

    public String draw()
    {
        StringBuilder result = new StringBuilder();
        for( int ucount = size; ucount &gt; 0; ucount-- )
        {
            appendSpaces( result, ucount - 1 );
            appendStars( result, size - ucount + 1 );
            newLine( result );
        }

        for( int lcount = 1; lcount &lt; size; lcount++ )
        {
            appendSpaces( result, lcount );
            appendStars( result, size - lcount );
            newLine( result );
        }
        return result.toString();
    }

    private void newLine( StringBuilder result ) // just for better readability
    {
        result.append( "\n" );
    }

    private void appendStars( StringBuilder result, int count ) // just for better readability
    {
        repeat( result, "* ", count );
    }

    private void appendSpaces( StringBuilder result, int count ) // just for better readability
    {
        repeat( result, " ", count );
    }

    private void repeat( StringBuilder result, String string, int count )
    {
        for( int c = 0; c &lt; count; c++ )
            result.append( string );
    }
}


If you want to get rid of one of the loops you could even merge it to:

public String draw()
{
    StringBuilder result = new StringBuilder();
    for( int ucount = size; ucount &gt;= -size; ucount-- )
    {
        boolean isMiddleRows = ucount == 0 || ucount == -1;
        if( isMiddleRows ) continue;
        appendSpaces( result, Math.abs( ucount ) - 1 );
        appendStars( result, size - Math.abs( ucount ) + 1 );
        newLine( result );
    }
    return result.toString();
} 


It's pretty cool to have enough tests do try such refactoring :)