javajustifytext-justify

How to implement justify()-method in Java


I am trying to make my own justify()-method that takes a string and an integer as input, and fils in spacing so that the string has the same length as the given integer. I have followed the answers to this question to do it.

I want my code to work somethinglike this:

Input = "hi hi hi" 20
Output = hi       hi       hi

My code looks like this:

//Add spaces to string until it is of desired length
static String justify(StringBuilder text, int width) {

    String[] inputLS = text.toString().split(" ");                //Split string into list of words

    //Sum the length of the words
    int sumOfWordLengths = 0;
    for (String word : inputLS){ sumOfWordLengths += word.length(); }

    int padding = width-sumOfWordLengths;                         //How much spacing we need
    String lastWord = inputLS[inputLS.length - 1];                //Last word in list of strings

    //Remove the last word
    ArrayList<String> withoutLast = new ArrayList<>
                                (Arrays.asList(inputLS).subList(0, inputLS.length - 1));

    StringBuilder result = new StringBuilder();                   //Initialize StringBuilder

    //Iterate over strings and add spacing (we do not add spacing to the last word)
    while (padding > 0){
        for(String word : withoutLast){
            result.append(word).append(" ");
            padding--;
        }
    }
    result.append(lastWord);                                      //Add the last word again
    return result.toString();
}


public static void main(String[] args) {
        // IO
        Scanner scanner = new Scanner(System.in);                       //Initialize scanner
        System.out.println("Please enter a string and an integer: ");   //Ask for input from user

        String line = scanner.nextLine();          //Get input-string from user
        String[] strings = line.split(" ");        //Split string at " " into list of strings
        String text = strings[0];                  //Get first element from list as string
        int width = Integer.parseInt(strings[1]);  //Get second element from list as an int

        // Create a string with three times the input text with spaces between
        StringBuilder forJustify = new StringBuilder();
        for(int i=0; i<3; i++){ forJustify.append(text).append(" "); }

        // Make sure the length of the string is less than the given int
        if (text == null || text.length() > width) {
            System.out.println(text);
            throw new IllegalArgumentException("Whoops! Invalid input. Try again.");
        }

        System.out.println("Gave this as input:\t" + forJustify);
        System.out.println("Justify:\t\t\t" + justify(forJustify, width));
    }

Which gives me this output:

Please enter a string and an integer: 
hi 20
Gave this as input: hi hi hi 
Justify:            hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi

But I want this output:

Please enter a string and an integer: 
hi 20
Gave this as input: hi hi hi 
Justify:            hi       hi       hi

I know that there's something wring with the while-loop, but I don't understand how to fix it. All help is appreciated!


Solution

  • This solution is super simple using printf()

    String test = "hi hi hi";
    String[] tokens = test.split(" ");
    int spacing = 20;
    for (String token : tokens) {
        System.out.printf("%" + spacing + "s", token);          
    }
    System.out.println();
    

    The output (right-justified):

                      hi                  hi                  hi
    

    For left-justify solution, just add - after the percent sign

    for (String token : tokens) {
        System.out.printf("%-" + spacing + "s", token);         
    }
    System.out.println();
    

    outputs:

    hi                  hi                  hi                  
    

    UPDATE: Extracting justification as a function:

    public static void justify(int spacing, boolean leftJustified, String...words) {
        for (String word : words) {
            System.out.printf("%" + (leftJustified ? "-" : "") + spacing + "s", word);                      
        }
        System.out.println();
    }
    

    To use,

    public static void main(String[] args) {
        String test = "hi hi hi";
        String[] tokens = test.split(" ");
        int spacing = 20;
            
        justify(spacing, false, tokens); // right-justified
        justify(spacing, true, tokens); // left-justified
    }