0

I have a text file which contains multiple titles and descriptive text below each title. I am trying to add each title to a hashmap key and the descriptive text to the value but cannot figure out how to iterate over this text file and properly parse the information. The title will ALWAYS contain an empty line before and after the title (unless it is the first line) and the value will ALWAYS be the text immediately after the respective title UNTIL the next title is reached in the file. The user will be given a list of keys to choose from in the program and the corresponding value will be printed.

Example Text File

Title

text
text
text

text
text

Title

text
text
text
text

The text file has multiple titles in the file and must be a single file.

Code

  private static HashMap<String, ArrayList<String>> hashmap = new HashMap<>();
  public static void processTextFile(ArrayList array) {
//Place first line in hashmap key
    hashmap.put((String) array.get(0), new ArrayList<>());
//Iterate over text file and add titles which have null spaces before and after as a key
    for (int i = 0; i < array.size(); i++) {
      if (array.get(i).equals("") && array.get(i + 2).equals("")) {
        hashmap.put((String) array.get(i + 1), new ArrayList<>());
      }
    }
  }

Desired Result

Please select a Title:
*user types a specific title*
Title

text
text
text

text
text
  • 2
    Is there any marker or pattern which differentiates between title and description? Is the number of lines fixed for description? Does the title follows some pattern. How do you know by looking at text, that it is a title not description? – Anurag Anand Sep 18 '22 at 19:47
  • The title will always have a null line before and after. The description will never have a null line before AND after BUT it could have a null line after a short blurb which could vary in size. There are no other markers. – Kyle Sinclair Sep 18 '22 at 19:52
  • Yes. I've updated for desired result as well – Kyle Sinclair Sep 18 '22 at 19:56
  • Keep proper formatting and am new – Kyle Sinclair Sep 18 '22 at 20:00
  • The hashmap would consist of the title as a key (which can be distinguished from an empty line both above and below) and the value as the text immediately following until the next key/title. – Kyle Sinclair Sep 18 '22 at 20:06
  • idk, Im just passing an array in which contains the text file – Kyle Sinclair Sep 18 '22 at 20:26

1 Answers1

0

Assuming that there would be no single-line paragraphs (that can be confused with a title) and you don't need to store empty strings (if you need them remove the condition if (!list.get(i).isEmpty())), you can apply the following logic to populate the map with titles used a keys and Lists containing lines of text as values:

private static Map<String, List<String>> textByTitle = new LinkedHashMap<>();

public static void processText(List<String> list) {
    List<String> text = new ArrayList<>(); // text
    textByTitle.put(list.get(0), text);    // the first line is treated as a title
    
    for (int i = 1; i < list.size(); i++) {
        if (i < list.size() - 1 && list.get(i - 1).isEmpty() && list.get(i + 1).isEmpty()) {
            text = new ArrayList<>();           // reinitializing the text
            textByTitle.put(list.get(i), text); // adding an entry that correspond to a new title
        } else if (!list.get(i).isEmpty()) {
            text.add(list.get(i));              // adding the next line of text
        }
    }
}

main()

public static void main(String[] args) {
    List<String> myText = List.of(
        "Title1",
        "",
        "line1",
        "line2",
        "",
        "Title2",
        "",
        "line1",
        "line2",
        "line3"
    );
    // populating the map
    processText(myText);
    // displaying the result
    textByTitle.forEach((title, text) -> System.out.println(title + " -> " + text));
}

Output:

Title1 -> [line1, line2]
Title2 -> [line1, line2, line3]

Note:

  • Use LinkedHashMap to preserve the order of titles.
  • Avoid using collections of row type (without generic type variable specified).
  • Leverage abstractions, write your code against interfaces. Don't make your code dependent on concrete classes like HashMap, ArrayList, etc. See What does it mean to "program to an interface"?
  • Avoid meaningless names like hashmap. The name of the variable should convey what it is meant to store (See Self-documenting code).
Alexander Ivanchenko
  • 25,667
  • 5
  • 22
  • 46