Formatting toString method - java

I have a toString() method from my class that takes the information from the object and puts it into a string to be printed.
This is what it should look like:
Susan 70 <Average C
Alexander 80 >Average B
, but I'm having trouble formatting my toString() method. This is what it looks like this right now which is very unorganized.
public String toString() {
return ("\n" + fullName +
" " + relativeScore +
" " + testScore);
}
I would normally use printf, but since it's a return statement I can't use it. Any help would be much appreciated.

Depending on what you want to achieve, you could simply use String#format, for example:
System.out.println(String.format("%-10s %d %10s %5s", "Susan", 70, "<Average", "C"));
Which outputs
Susan 70 <Average C
For more details have a look at this example and Formatter

String.format method returns a new String object, so you can use it rather than printf, for instance:
public String toString() {
return String.format("%s\t%3d\t%s", fullName, relativeScore, testScore);
}

You could use String.format() and do it just like you would do with printf()
return String.format("whatever comes here");

you're doing it wrong way. Susan is 5 letter word and Alexander is 9 letter word. So if susan is followed by 10 white spaces then alexander should be followed by 10-9+5= 6 white spaces. You should consider the length of fullname in your code.

Related

java parsing array input control

Thanks for checking out my question.
Starting off, the program has the following goal; the user inputs currency formatted as "xD xC xP xH"; the program checks the input is correct and then prints back the 'long' version: "x Dollars, x Cents, x Penny's, x half penny's"
Here I have some code that takes input from user as String currencyIn, splits the string into array tokens, then replaces the D's with Dollars etc and prints the output.
public class parseArray
{
public parseArray()
{
System.out.print('\u000c');
String CurrencyFormat = "xD xS xP xH";
System.out.println("Please enter currency in the following format: \""+CurrencyFormat+"\" where x is any integer");
System.out.println("\nPlease take care to use the correct spacing enter the exact integer plus type of coin\n\n");
Scanner input = new Scanner(System.in);
String currencyIn = input.nextLine();
currencyIn.toUpperCase();
System.out.println("This is the currency you entered: "+currencyIn);
String[] tokens = currencyIn.split(" ");
for (String t : tokens)
{
System.out.println(t);
}
String dollars = tokens[0].replaceAll("D", " Dollars ");
String cents = tokens[1].replaceAll("C", " cents");
String penny = tokens[2].replaceAll("P", " Penny's");
String hPenny = tokens[3].replaceAll("H", " Half penny's");
System.out.println(" "+dollars+ " " +cents+ " " +penny+ " " +hPenny);
input.close();
}
}
Question 1: At the moment the program prints out pretty anything you put in. how do I establish some input control? I've seen this done in textbooks with switch statement and a series of if statements, but were too complicated for me. Would it parse characters using charAt() for each element of the array?
Question 2: Is there a 'better' way to print the output? My friend said converting my 4 strings (dollars, cents, penny's, hpenny's) into elements 0, 1, 2, 3 of a new array (called newArray) and print like this:
System.out.println(Arrays.toString(newArray));
Many thanks in advance.
There is a neat solution, involving Regular Expressions, Streams and some lambdas. Core concept is that we define the input format through a regular expression. We need some sequence of digits, followed by a 'D' or a 'd', followed by a " ", followed by a sequence of digits, followed by a C or c,... I will skip derivation of this pattern, it is explained in the regular expression tutorial I linked above. We will find that
final String regex = "([0-9]+)[D|d]\\ ([0-9]+)[C|c]\\ ([0-9]+)[P|p]\\ ([0-9]+)[H|h]";
satisfies our needs. With this regular expression we can now determine whether our input String has the right format (input.matches(regex)), as well as extract the bits of information we are actually interested in (input.replaceAll(regex, "$1 $2 $3 $4"). Sadly, replaceAll yields another String, but it will contain the four digit sequences we are interested in, divided by a " ". We will use some stream-magic to transform this String into a long[] (where the first cell holds the D-value, the second holds the C-value,...). The final program looks like this:
import java.util.Arrays;
public class Test {
public static void main(String... args) {
final String input = args[0];
final String regex =
"([0-9]+)[D|d]\\ ([0-9]+)[C|c]\\ ([0-9]+)[P|p]\\ ([0-9]+)[H|h]";
if (input.matches(regex) == false) {
throw new IllegalArgumentException("Input is malformed.");
}
long[] values = Arrays.stream(input.replaceAll(regex, "$1 $2 $3 $4").split(" "))
.mapToLong(Long::parseLong)
.toArray();
System.out.println(Arrays.toString(values));
}
}
If you want to have a List<Long> instead a long[] (or a List<Integer> instead of an int[]), you would use
List<Long> values = Arrays.stream(input.replaceAll(regex, "$1 $2 $3 $4").split(" "))
.map(Long::parseLong)
.collect(Collectors.toList());
It is necessary to change mapToLong to map to receive a Stream<Long> instead of a LongStream. I am sure that one could somehow write a custom Collector for LongStream to transform it into a List<Long>, but I found this solution more readable and reliable (after all, the Collector used comes from Oracle, I trust they test their code extensively).
Here is some example call:
$> java Test "10D 9c 8p 7H"
[10, 9, 8, 7]
$> java Test "10E 9C 8P 7H"
Exception in thread "main" java.lang.IllegalArgumentException: Input is malformed.
at Test.main(Test.java:10)
$> java Test "10D 9C 8P 7H 10D 9C 8P 7H"
Exception in thread "main" java.lang.IllegalArgumentException: Input is malformed.
at Test.main(Test.java:10)
Question1
You can actually check if the input is what it's supposed to be with simple checks. For example, you can check the first element like this:
if(tokens[0].charAt(1).equals("D"))
return true;
else
return false;
Another way to check if the input is correct is by using Regular Expressions, but I assume you are a beginner and this is too much trouble for you, although it is the better way. So I leave it to you to look through it later.
Question2
You can actually listen to your friend and do as they said. You can write it as follows:
for(int i = 0; i < 4; i++)
System.out.print(" " + tokens[i])
System.out.println();
Or you may use
System.out.println(Arrays.toString(newArray));
And you have saved newArray like this:
newArray[0] = " " + tokens[0];
you could use the .equals() method to see if what a user has typed in matches what you have
if (currencyIn.equals("CurrencyFormat"))
{
...
}
this is probably the simplest way i can think of!

Java toString() printing issues

I am currently using an toString() method to print out an array list. It works but the output comes out all wonky in the console when it prints out. I was wondering is anyone would point out to me where i am going wrong or even direct me to a tutorial that would help better explain his type of formatting.
Method i am using:
rental number, release and releaseYear are all ints.
film , fname, studio are all strings
public String toString()
{
//Returns a String
return String.format("DVDDetails [%s |\t\t %s \t\t | \t\t %s | %s | %s| %s| ]",rental, fFName, FAName, studio, releaseYear);
}
Because the fFname results in a string with varrying number of characters, it looks like that. The formater has no idea of the next line so the tab is only effective on its own line. you better off add spaces depending on the length of the string you have. count number of characters and add spaces. have a max value with the largest length of fFname and other strings values.
You can look in java documetns for inserting spaces in formatting. something like"%-20s %s"

Console output alignment

Hi I'm trying to align output to the console window in Java using NetBeans.
ATM I have a collection of MP3Tracks (classes) in an arraylist. The user is able to sort the track by artist, album & track name etc after the sort the reordered list is via the console:
System.out.println(vector);
My MP3Track class overrides toString():
#Override
public String toString(){
return(String.format("Track No: %-8s Track Title: %-25s Artist Name: %-15s Album Name: %-20s Track Length: %-10s", trackNo , trackTitle, artistName, albumName, trackLength + "\n"));
}
This solution works for all but the first line which is line and the first and last digit output is []. I would like all lines to line up and to remove both [] at the beginning and end. I'm a first year Software Engineering student and this in my first assignment in Java so please excuse my inexperience!
I would very much appreciate some suggestion here.
Many thanks in advance..
You are printing your vector using
System.out.println(vector);
it calls vector's toString() method to get its String representation and Java's String representation for Collections is formatted like:
[element1.toString(), element2.toString, ... ]
You can just iterate over your vector and print your MP3Tracks:
for (MP3Track mp3Track : vector) {
System.out.println(mp3Track);
}
And remove the \n at the end of your the string representation of MP3Track, it would be nicer that way.
Alternatively, you create a subclass of Vector class and override its toString() method and use it but that would be overkill imo.
You should not rely on toString() to present data to the end-user. toString is meant for debug purposes. The braces are there because the array's toString prints them.
When you want to present data to the user, you should use an external viewer class, that prints things just like they should be printed, according to you.
This, or you can create a List implementation that delegates to a JavaSE collection and overrides toString, but I'd really dislike this way of doing things.
Something like:
public class TrackViewer {
private static final String FORMAT
= "Track No: %-8s Track Title: %-25s "
+ "Artist Name: %-15s Album Name: %-20s "
+ "Track Length: %-10s\n";
private String getTrackLine(Track t) {
return String.format(FORMAT,
t.getTrackNo(),
t.getTrackTitle(),
t.getArtistName(),
t.getAlbumName(),
t.getTrackLength());
}
public void listTracks(Iterable<Track> tracks) {
StringBuilder bdr = new StringBuilder();
for (Track t : tracks) {
bdr.append(getTrackLine(t));
}
System.out.print(bdr.toString());
}
}

Is there a left()-function for Java strings?

I have an string str of unknown length (but not null) and a given maximum length len, this has to fit in. All I want to do, is to cut the string at len.
I know that I can use
str.substring(0, Math.min(len, str.length()));
but this does not come handy, if I try to write stacked code like this
code = str.replace(" ", "").left(len)
I know that I can write my own function but I would prefer an existing solution. Is there an existing left()-function in Java?
There's nothing built in, but Apache commons has the StringUtils class which has a suitable left function for you.
If you don't want to add the StringUtils Library you can still use it the way you want like so:
String string = (string.lastIndexOf(",") > -1 )?string.substring(0, string.lastIndexOf(",")): string;
Use Split.
String str = "Result string Delimiter Right String";
System.out.println(str.split("Delimiter")[0].trim());
Output: "Result string"
No there is not left() in the String class, as you can refer API. But as #Mark said Apache StringUtils has several methods: leftPad(), rightPad(), center() and repeat(). You can also check
this:http://www.jdocs.com/lang/2.1/org/apache/commons/lang/StringUtils.html
You can use String Format
In this example the format specifier "%-9s" means minimum 9 characters left justified (-).
"%-9.9s" means maximum 9 characters.
System.out.println (String.format("%-9.9s","1234"));
System.out.println (String.format("%-9.9s","123456789ABCD"));
int len=9;
System.out.println (String.format("%-"+len+"."+len+"s","123456789ABCD"));
Prints:
1234
123456789
123456789
in OP's case it would be something like this:
static final int MAXLEN=9;
code = String.format("%-"+MAXLEN+"."+MAXLEN+"s",str.replace(" ", ""));
put the below function in a class:
public static String getLeftString(String st,int length){
int stringlength=st.length();
if(stringlength<=length){
return st;
}
return st.substring((stringlength-length));
}
in my case I want to get date only.
String s = "date:2021-01-01";
int n = s.length() - 10; //10 was the length of the date
String result = s.substring(n);
the result will be "2021-01-01";

How to use String.format() in Java to replicate tab "\t"?

I'm printing data line by line and want it to be organized like a table.
I initially used firstName + ", " + lastName + "\t" + phoneNumber.
But for some of the larger names, the phone number gets pushed out of alignment
I'm trying to use String.format() to achieve this effect. Can anyone tell me the format syntax to use?
I tried String.format("%s, %s, %20s", firstName, lastName, phoneNumber), but that's not what I want. I want it to look like this:
John, Smith 123456789
Bob, Madison 123456789
Charles, Richards 123456789
Edit:
These answers seem to work for System.out.println(). But I need it to work for a JTextArea. I'm using textArea.setText()
Worked it out. JTextArea doesn't use monospaced fonts by default. I used setFont() to change that, and now it works like a charm. Thank you all for the solutions.
consider using a negative number for your length specifier: %-20s. For example:
public static void main(String[] args) {
String[] firstNames = {"Pete", "Jon", "Fred"};
String[] lastNames = {"Klein", "Jones", "Flinstone"};
String phoneNumber = "555-123-4567";
for (int i = 0; i < firstNames.length; i++) {
String foo = String.format("%-20s %s", lastNames[i] + ", " +
firstNames[i], phoneNumber);
System.out.println(foo);
}
}
returns
Klein, Pete 555-123-4567
Jones, Jon 555-123-4567
Flinstone, Fred 555-123-4567
Try putting the width into second placeholder with - sign for right padding as:
String.format("%s, %-20s %s", firstName, lastName, phoneNumber)
This will give the specified width to the second argument(last name) with right padding and phone number will start after the specified width string only.
EDIT: Demo:
String firstName = "John";
String lastName = "Smith";
String phoneNumber = "1234456677";
System.out.println(String.format("%s, %-20s %s",firstName, lastName, phoneNumber));
prints:
John, Smith 1234456677
The only alternative is loop the names list, calculate the maximum length of the String, and add whitespaces as needed after every name to ensure that all the numbers begin at the same column.
Using tabs has the disavantage that you cannot know a priori how many whitespace are equivalent to a tab, since it is dependent of the editor.

Categories