Read a TXT file and put its content in a LinkedList

0

I need to read a TXT file and add its contents to variables in a list. However, the file does not have the same amount of characters in all rows. In the entry we have a sequence, two numbers in a row and a sequence of characters in another.

Example input:

2 1
ADEEDAE
3 2
AEAEDDA
1 4
AADDEAD

My goal is to put 2 in a variable, 1 in another, ADEEDAE in another and so on.

When I read the file I end up putting everything in position 0 of the list and I'm having difficulty assigning values.

Can anyone help me?

Code:

public static List<String[]> read(String file){
    List<String[]> data = new LinkedList<String[]>();
    String dataRow;

    try {
        BufferedReader br = new BufferedReader(new FileReader(file));
        while((dataRow = br.readLine())!=null) {
        String[] dataRecords = dataRow.split(" ");
        data.add(dataRecords);
        }       
    } catch (FileNotFoundException e) {
        System.out.println("Couldn't find the File.");
        e.printStackTrace();
    } catch (IOException e) {
        System.out.println("Couldn't read the line of the File.");
        e.printStackTrace();
    }

    return data;
}

Then, to print variables I use:

for(String[] robot : actionsToExecute) {
    System.out.println(robot[0]);
    System.out.println(robot[1]);
    System.out.println(robot[2]);
}

The idea was to use for to assign values:

    for(String[] robot : actionsToExecute) {
    String var1 = robot[0];
    ...
}
    
asked by anonymous 19.02.2018 / 21:16

2 answers

0

I would do the following:

import java.io.File;
import java.io.IOException;
import java.nio.charsets.StandardCharsets;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;

public class Mundo {

    private final int largura;
    private final int altura;
    private final List<Comando> comandos;

    public static Mundo read(String file) throws IOException {
        return new Mundo(Files
                .readAllLines​(new File(file).toPath(), StandardCharsets.UTF_8));
    }

    public Mundo(List<String> linhas) {
        if (linhas.isEmpty()) throw new IllegalArgumentException();
        this.comandos = new ArrayList<>(100);
        boolean primeiro = true;
        int w = 0;
        int h = 0;
        for (String linha : linhas) {
            if (primeiro) {
                String[] partes = linha.split(" ");
                if (partes.length != 2) throw new IllegalArgumentException();
                w = Integer.parseInt(partes[0]);
                h = Integer.parseInt(partes[1]);
                primeiro = false;
            } else {
                interpretarLinha(linha);
            }
        }
        this.largura = w;
        this.altura = h;
        return comandos;
    }

    private void interpretarLinha(String linha) {
        String[] partes = linha.split(" ");
        if (partes.length == 1) {
            interpretarSequencia(linha);
        } else if (partes.length == 2) {
            ComandoPosicionar cp = ComandoPosicionar.interpretar(linha);
            comandos.add(cp);
        }
        throw new IllegalArgumentException();
    }

    private void interpretarSequencia(List<String> linhas) {
        for (char c : linha.toCharArray()) {
            Comando co = identificar(String.valueOf(c));
            comandos.add(co);
        }
    }

    private Comando identificar(char c) {
        if (c == 'R') return new ComandoR();
        if (c == 'M') return new ComandoM();
        if (c == 'L') return new ComandoL();
        throw new IllegalArgumentException();
    }

    public void interpretar() {
        for (Comando c : comandos) {
            c.interpretar(this);
        }
    }
}
public interface Comando {
    public void interpretar(Mundo m);
}
public class ComandoR implements Comando {
    @Override
    public void interpretar(Mundo m) {
        // ...
    }
}
public class ComandoL implements Comando {
    @Override
    public void interpretar(Mundo m) {
        // ...
    }
}
public class ComandoM implements Comando {
    @Override
    public void interpretar(Mundo m) {
        // ...
    }
}
public class ComandoPosicionar implements Comando {
    private final int x;
    private final int y;

    public static ComandoPosicionar interpretar(String linha) {
        String[] partes = linha.split(" ");
        int px = Integer.parseInt(partes[0]);
        int py = Integer.parseInt(partes[1]);
        return new LinhaNumerica(py, py);
    }

    private ComandoPosicionar(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    @Override
    public void interpretar(Mundo m) {
        // ...
    }
}

In this code, the Mundo class represents your world, containing a width, height, and a sequence of commands that it compiles. The first line of the file has special handling. The other lines can be numeric or textual and represent sequences of commands, they are separated by the interpretarLinha method of class Mundo .

The number line corresponds to a command with two numbers that indicate a position.

The textual line corresponds to a sequence of commands, where each command corresponds to a character M , L or R , and the interpretarSequencia method of Mundo is responsible for separating them and method identificar to know who is who.

In the Comando interface, there is a method that tells how it should be interpreted, with all implementations of the interface having it. In the Mundo class, the interpretar() method will process all of these commands.

That way, you should not have much trouble adding new commands if you need to, and this will not affect other classes than the Mundo class.

Reading the contents of the file is done with the Files.readAllLines​(new File(file).toPath(), StandardCharsets.UTF_8) that will get the contents of the file and return a List<String> containing all the lines. Do not "eat" the resulting IOException and proceed as if nothing had happened.

Your question is more or less a XY problem . Your real problem (X) is how to turn this file into a world, and that's what I answered here. The problem you presented (Y) is about reading the contents of the file and putting it in LinkedList , but what you want is much more than that.

    
19.02.2018 / 22:18
0

This is more or less a XY problem . Your real problem (X) is how to turn this file into a world and that's what I replied in the other answer .

However, if for some reason you only want the answer to the problem you presented (Y), which is how to put it all into LinkedList , this would be:

try {
    List<String[]> lista = new LinkedList<>();
    Files.readAllLines​(new File(file).toPath(), StandardCharsets.UTF_8)
            .stream()
            .map(s -> s.split(" "))
            .forEach(lista::add);
    return lista;
} catch (IOException e) {
     // ...
}

Leaving the exception aside and assuming you just return a list, instead of having to be specifically a LinkedList :

return Files.readAllLines​(new File(file).toPath(), StandardCharsets.UTF_8)
        .stream()
        .map(s -> s.split(" "));
    
19.02.2018 / 22:32