What you're looking for is called "fixed column width" formatting. The easiest way to achieve it is to use the printf method. In your case, you'd do something like this:
System.out.println("Grade Count %");
System.out.println("----- ----- ------");
for (Grade g : grades) {
System.out.printf("%-5s %5d %6.2f%n",
g.getGrade(), g.getCount(), g.getPercent());
}
The first argument to printf is a format string that includes both fixed text (here just some spaces) and format specifiers that start with a % and end with a letter; the remaining arguments are the data to be formatted. Here's a brief breakdown of the format string in this example:
%-5s matches with the g.getGrade() argument; the 5 means a fixed field width of 5 columns, the - means left-justify, the s means we're formatting a String argument
%5d matches with the g.getCount() argument; the d means we're formatting a decimal integer (int, long, or BigDecimal) number, 5 is the field width, and the lack of a - implies right-justification;
%6.2f matches with the g.getPercent() argument; the f means we're formatting a floating-point (float, double or BigDecimal) number, 6 is the overall field width, .2 means there will be 2 digits after the decimal point, and no - means to right-justify.
For a more complete discussion, read format strings.
String.formatmethod: docs.oracle.com/en/java/javase/14/docs/api/java.base/java/lang/… (System.out.printfis also pretty much identical), as well as the formatting guide: docs.oracle.com/en/java/javase/14/docs/api/java.base/java/util/… You can use one of the padding rules (like%[...]s) to control how many spaces appear before or after the arguments of each data line (grade, count, percentage). You shouldn't have to test the actual value to determine the amount of space.