Repare que vc sempre imprime o espaço, ou seja, depois que imprimir o asterisco, vc coloca um espaço a mais.
Mas o correto é imprimir ou o asterisco, ou o espaço (apenas um deles), então deveria ter um else
aí:
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (i == 0 || i == 8) {
System.out.print("*");
} else {
if (j == 0 || j == 8) {
System.out.print("*");
} else { // <----- ***** AQUI *****
System.out.print(" ");
}
}
}
System.out.println();
}
Agora sim, se for a primeira ou última coluna, imprime o asterisco. Caso contrário, imprime o espaço.
Só por curiosidade, a partir do Java 8, daria para usar join
juntamente com nCopies
para repetir a mesma string várias vezes:
int altura = 9, largura = 9;
String borda = "*", meio = " ";
for (int i = 0; i < altura; i++) {
if (i == 0 || i == altura - 1) {
System.out.println(String.join("", Collections.nCopies(largura, borda)));
} else {
System.out.println(borda + String.join("", Collections.nCopies(largura - 2, meio)) + borda);
}
}
E a partir do Java 11 podemos usar o método repeat
para obter o mesmo resultado. Ou seja, o código ficaria assim:
int altura = 9, largura = 9;
String borda = "*", meio = " ";
for (int i = 0; i < altura; i++) {
if (i == 0 || i == altura - 1) {
System.out.println(borda.repeat(largura));
} else {
System.out.println(borda + meio.repeat(largura - 2) + borda);
}
}
Uma outra abordagem
Em vez de pensar em cada elemento individualmente, pense em termos de linhas: repare que em todas as linhas o primeiro e último caracteres são sempre o mesmo (o que chamei de borda
). O que muda é apenas o “recheio” (na primeira e última linha é o mesmo caractere da borda
, nas demais é o outro caractere, que chamei de meio
).
Ou seja, cada linha é composta de um caractere da borda
no início e outro no fim. E no meio vc preenche com um caractere que pode ser a borda
(quando a linha é a primeira ou a última), ou o meio
(nas outras linhas). Ficaria assim:
int altura = 9, largura = 9;
String borda = "*", meio = " ";
for (int i = 0; i < altura; i++) {
// se é a primeira ou última linha, usa o caractere da borda
// senão usa o outro caractere ("meio")
String recheio = i == 0 || i == altura - 1 ? borda : meio;
// uma borda no início e outra no fim, e no meio o "recheio"
System.out.println(borda + recheio.repeat(largura - 2) + borda);
}
Mas claro, se a ideia for fazer os loops “na mão”, sem usar métodos prontos, daria para seguir a mesma ideia acima:
int altura = 9, largura = 9;
String borda = "*", meio = " ";
for (int i = 0; i < altura; i++) {
String recheio = i == 0 || i == altura - 1 ? borda : meio;
System.out.print(borda);
for (int j = 0; j < largura - 2; j++) {
System.out.print(recheio);
}
System.out.println(borda);
}