mastercoder
mastercoder

Reputation: 17

Dynamic way to read a file in Java

I have the following piece of code in my reading File method:

FileReader fileReader = new FileReader(fName);
bf = new BufferedReader(fileReader);
while ((line = bf.readLine()) != null) {
    if (line.contains("Worker")) {
        info  = line.split(" ");
        int x = Integer.parseInt(info[1]);
        int y = Integer.parseInt(info[2]);
        worker = new Worker(new Point(x, y);
        globalList.add(worker);
    }
    if (line.contains("Work")) {
        info  = line.split(" ");
        int x = Integer.parseInt(info[1]);
        int y = Integer.parseInt(info[2]);
        work = new Work(new Point(x, y);
        globalList.add(work);                   
    }
    if (line.contains("Bulldozer")) {
        info  = line.split(" ");
        int x = Integer.parseInt(info[1]);
        int y = Integer.parseInt(info[2]);
        bulldozer = new Bulldozer(new Point(x, y);
        globalList.add(bulldozer);                  
    }
}

With this piece of code I'm reading from a file that looks like this:

Worker 5 0
Bulldozer 7 5
Work 4 2
Work 4 8

I am using BufferedReader to do this, I am creating instances of a class in this case classes Worker, Bulldozer and Work, reading the word in the file(that is the name of the class) and getting the x and y position, and add that object to a list.

And this works perfectly, my problem is that this looks really hard coded and that's not a good idea, since this a school project, so do you guys have any tip to help me make this code a bit more dynamic, maybe with just on if statement?

Upvotes: 0

Views: 2039

Answers (1)

Piotr Wilkin
Piotr Wilkin

Reputation: 3491

Basically, all three branches of your if do the same thing - they read two integers, prepare a point, then inject it into an object.

The only thing that varies is the first string and the class name. With reflection, you could make it universal - search the package for the class named like the string, create the Point, then call a single-argument constructor of the class.

Without reflection, you can still extract it by a method that takes as arguments a String and a Function<Point, Object> that serves as the factory.

The method would do this:

public void readIfMatches(String line, String match, Function<Point, Object> factory) {
    if (line.contains(match)) {
        String info  = line.split(" ");
        int x = Integer.parseInt(info[1]);
        int y = Integer.parseInt(info[2]);
        globalList.add(factory.apply(new Point(x, y));
    }
}

Then you call the three iterations like this:

readIfMatches(line, "Bulldozer", Bulldozer::new)

Upvotes: 1

Related Questions