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
CodePudding user response:
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 List
s 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).