0

I am creating a piece of code to take a hashmap called wordFrequencies, which contains some words and how many times they appear in a given string.

To spare details, the words need to line up so I am trying to create code to add spaces to the start of the words until they are all in alignment. I am doing this by comparing their lengths.

The issue I am having is with the while loop, as word is defined only in the for loop and I am not sure how to define it to be used within the while loop, as there is know such thing as a "while each" loop.

  // loop to determine length of longest word

        int maxLength = 0;

        for (String word : wordFrequencies.keySet()){
            if (word.length() > maxLength) {
                maxLength = word.length();
                }
            }

        // loop to line up the words in the graph / table

        while (word.length() < maxLength){
            word = " " + word;   // if word is shorter than longest word, add spaces to the start until they line up
        }
Charlie
  • 220
  • 1
  • 9
  • @xerx593 yes. I need to add spaces to the beginning of the word until is the same length as the longest word. The for loop dealt with determining how long the longest word is, but its the while loop I'm struggling with – Charlie Mar 10 '20 at 21:19
  • You might want to use String.format() which uses printf formatting and can right or left justify values. – NomadMaker Mar 11 '20 at 00:57

2 Answers2

1

You just need to loop through the set again.

The problem with doing this in a loop: word = " " + word; is that it is not efficient to concatenate strings in loops using the + operator . On Java 11+ you can use String repeat(int count) to get the spaces. On Java 8 you can use StringBuilder append(String str) in a loop to get the spaces.

Also you cant edit the keys in the HashMap. You can remove one entry and add a new one, but it would be better to use a function to format the words for output.

Here is an example

public class scratch {
 public static void main(String[] args) {
    int maxLength = 0;
    HashMap<String, Integer> wordFrequencies = new HashMap<>();
    wordFrequencies.put("bla", 0);
    wordFrequencies.put("blaaaa", 0);
    wordFrequencies.put("blaaaaaaaaaaaaaaaa", 0);

    for (String word : wordFrequencies.keySet()) {
        if (word.length() > maxLength) maxLength = word.length();
    }

    for (String word : wordFrequencies.keySet()) {
        System.out.println(addSpace(word, maxLength));
    }

 }

 public static String addSpace(String word, int maxLength) {
    StringBuilder newWord = new StringBuilder();
    for (int i = 0; i < maxLength - word.length(); i++) {
        newWord.append(" ");
    }
    return newWord.append(word).toString();

    // On Java 11+ you can use String repeat(int count)
    //return " ".repeat(maxLength - word.length()) + word;
}

}
HomeIsWhereThePcIs
  • 869
  • 10
  • 28
1

The main problem: word is not visible in this scope - solution: You have to iterate once, to find maxLength, and iterate one more time to format "the keys". Additionally I wouldn't modify the input keys, but rather return a "formatted copy", like so:

int maxLength = Integer.MIN_VALUE;
for (String word : wordFrequencies.keySet()){
  if (word.length() > maxLength) {
    maxLength = word.length();
  }
}

// a new set for formatted words:
Set<String> formatted = new Set<>(wordFrequencies.size());
// repeat the above loop:
for (String word : wordFrequencies.keySet()){
    // (unfortunately), You have to nest the loop & spend 1 variable:
    String fWord = word;
    while (fWord.length() < maxLength){
        fWord = " " + fWord;   // string concatenation is considered "badong" (bad & wrong)
    }
    // now "put it in the case":
    formatted.add(fWord);
}

// return formatted;

Better approaches, than String +: How can I pad a String in Java?

xerx593
  • 5,580
  • 4
  • 23
  • 43
  • 'I wouldn't modify the input keys, but rather return a "formatted copy"'. Can you explain why? – Charlie Mar 10 '20 at 21:34
  • Also, a word can't be negative so why use MIN_VALUE? – Charlie Mar 10 '20 at 21:37
  • 1
    because, especially with few context: Where does it (the input) come from? Who will (want to) use it later on?? ..and because it's technically simpler;) – xerx593 Mar 10 '20 at 21:37
  • `MIN_VALUE` (its the lowest possible int value, so "always" a fail-safe initialization for find-max algorithm) ..`0` is enough in your case, but wit an "empty word list" ..the output (of findMaxLenght) would be identical to a "list filled with 0-legth-words only" ... `-1` suffcient. – xerx593 Mar 10 '20 at 21:42
  • and if you *want to modify* the input map: [Changing HashMap keys during iteration](https://stackoverflow.com/q/4235774/592355);) (also only via a temporary copy) – xerx593 Mar 10 '20 at 21:51
  • "You can never change a key value in a Map."^^ – xerx593 Mar 10 '20 at 21:56