Read a TXT file and put its content into a Linkedlist

Asked

Viewed 455 times

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 on all lines. In the input we have a sequence of two numbers in one line and a string in another.

Input example:

2 1
ADEEDAE
3 2
AEAEDDA
1 4
AADDEAD

My goal is to put 2 in one 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 difficulties in assigning values.

Can someone 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 the for to assign the values:

    for(String[] robot : actionsToExecute) {
    String var1 = robot[0];
    ...
}
  • Your question is confused. Also, if you are using a for it makes no sense to pick the position of the vector statically.

  • I simplified the question. @Giulianabezerra Let me try to explain what I wanted to try to do, as we have a Linked list at position 0 in the first iteration of for would have a value different from iteration 0 of the second iteration. xD is that right? eg: in the first iteration one would have 2 in the other the 3.

2 answers

0


Here’s what I’d do:

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 class Mundo represents his world, containing a width, a height and a sequence of commands he compiles. The first line of the file has special treatment. The other lines can be numerical or textual and represent sequences of commands, they are separated by the method interpretarLinha class Mundo.

The numeric line corresponds to a command with two numbers indicating a position.

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

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

That way, you shouldn’t have too much trouble adding new commands if you have to and it won’t affect classes other than the class Mundo.

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

Your question is more or less one 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 in LinkedList, but what you want is much more than that.

  • I really liked that answer, I’m going to try to apply it, I modified the question, because I didn’t think anyone was getting it. But I will try to apply what you answered. Thank you

  • @Excellent Matheus. I’m glad I helped. I just edited the answer to simplify a little bit.

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 answered in the other reply.

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

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 that just return a list, instead of having to be specifically one LinkedList:

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

Browser other questions tagged

You are not signed in. Login or sign up in order to post.