Transform text file to objects

In this example we will read each line in a file and convert it to a java object. There are many libraries that provide very similar functionality but it gets pretty easy with the introduction to java 8 functional programming features. In the event java 8 isn't yet available in your environment, you could perform almost the exact same behavior using guava. The trivia game program provided us with a use case where we needed to read a file and parse each line into a Question object. We will walk you through the process we took to achieve this.

To get us started, lets take a look at the triva.txt file. Each high level element is separated by a pipe and there are three pieces: question, multiple choice answers and the answer itself. The multiple choice question is separated by a comma and the answer is a number representing the index of the possible answers. For example, having an answer of 2 would represent the second element in the possible answers.

Which singer joined Mel Gibson in the movie Mad Max: Beyond The Thunderdome?|TINA TURNER,Hugh Keays-Byrne, Joanne Samuel, Roger Ward|1

Creating a Questions object

We will first create a POJO object that represents the higher level question. It will contain the question, possible answers and the answer to the question.

class Question {

    private String question;
    private List<String> possibleAnswers;
    private int answer;

    @Override
    public String toString() {
        return "Question [question=" + question + ", possibleAnswers="
                + possibleAnswers + ", answer=" + answer + "]";
    }
}

Creating java 8 function

Java 8 introduced functions which are commonly used to map from one object to another and is common when converting from an arraylist to a hashmap. In our case we have a string in which we want to convert it to a java object named Question.

There are a few things happening in the apply method. We will create a new Question object and then break the string apart and assign the elements to the properties of the Question. The overall line can be split on the pipe delimiter while the possible answers can be split on a comma. For each split operation we will use guava's splitter class trimming and removing empty strings.

Function<String, Question> mapLineToQuestion = new Function<String, Question>() {

    public Question apply(String line) {

        Question question = new Question();

        List<String> questionPieces = Splitter.on("|").trimResults()
                .omitEmptyStrings().splitToList(line);

        question.question = questionPieces.get(0);
        question.possibleAnswers = Splitter.on(",").trimResults()
                .omitEmptyStrings().splitToList(questionPieces.get(1));
        question.answer = Integer.parseInt(questionPieces.get(2));

        return question;
    }
};

Putting it together

Java 7 introduced the revamped Files api and java 8 introduce the ability to process a file as a stream. Combining these pieces we can read the file and process each line. Tying the mapLineToQuestion function we will convert each line to the Question object and then will convert the stream to arraylist.

@Test
public void test() throws IOException {

    List<Question> questions = Files
            .lines(Paths
                    .get("src/test/resources/com/levelup/java/io/trivia.txt"))
            .map(mapLineToQuestion).collect(Collectors.toList());

    logger.info(questions);

    assertTrue(questions.size() == 10);
}

Output

[
[question=Which singer joined Mel Gibson in the movie Mad Max: Beyond The Thunderdome?, possibleAnswers=[TINA TURNER, Hugh Keays-Byrne,  Joanne Samuel,  Roger Ward], answer=1], Question [question=Vodka, Galliano and orange juice are used to make which classic cocktail?, possibleAnswers=[HARVEY WALLBANGER,  Old Fashioned,  Manhattan,  Bloody Mary], answer=1], Question [question=Which American state is nearest to the former Soviet Union?, possibleAnswers=[Hawaii,  ALASKA,  California,  Florida], answer=2], Question [question=In which year did Foinavon win the Grand National?, possibleAnswers=[1967,  1988,  2900,  1340], answer=1], Question [question=At which battle of 1314 did Robert The Bruce defeat the English forces?, possibleAnswers=[BANNOCKBURN,  Sally Joe,  Gettysburg,  Shiloh], answer=1], Question [question=Consecrated in 1962, where is the Cathedral Church of St Michael?, possibleAnswers=[COVENTRY,  Church of Hope,  Sagrada Familia,   Notre Dame de Paris], answer=1], Question [question=On TV, who did the character Lurch work for?, possibleAnswers=[ADDAMS FAMILY,  Modern Family,  3.5 Men,  I ain't your momma], answer=1], Question [question=Which children's classic book was written by Anna Sewell?, possibleAnswers=[BLACK BEAUTY,  Where the red fern grows, Java control structures,  Something to do], answer=1], Question [question=How many tentacles does a squid have?, possibleAnswers=[TEN,  Eight,  Nine,  Five,  Four], answer=1], Question [question=Which reggae singing star died 11th May 1981?, possibleAnswers=[BOB MARLEY,  Jessica Dubroff,  Eddie Cochran,  Aaliyah], answer=1]]>