2015-06-07 18 views
6

Desidero leggere un file di testo che contiene String e alcuni numeri interi correlati a tale stringa.Ottenere dati interi da file txt in Java

Questa è la classe che ho dovuto scrivere il mio programma in:

public List<Integer> Data(String name) throws IOException { 
    return null; 
} 

devo leggere il file .txt e trovare il nome di quel file, con i suoi dati. E salvarlo in un ArrayList.

La mia domanda è come salvarlo nel ArrayList<Integer> quando ho String s nel List.
Questo è ciò che penso che vorrei fare:

Scanner s = new Scanner(new File(filename)); 
ArrayList<Integer> data = new ArrayList<Integer>(); 

while (s.hasNextLine()) { 
    data.add(s.nextInt()); 
} 
s.close(); 
+2

Volete trasformare stringa a intero? – Alexander

risposta

3

vorrei definire il file come un campo (in aggiunta al filename, e vi suggerisco di leggere che dalla cartella principale dell'utente) file

private File file = new File(System.getProperty("user.home"), filename); 

Quindi è possibile utilizzare l'operatore diamante <> quando si definisce il proprio List. Puoi usare un try-with-resources a close il tuo Scanner. Vuoi leggere per linee. E puoi split il tuo line. Quindi si verifica se la prima colonna corrisponde al nome. In tal caso, iterare le altre colonne sono analizzarle su int. Qualcosa di simile

public List<Integer> loadDataFor(String name) throws IOException { 
    List<Integer> data = new ArrayList<>(); 
    try (Scanner s = new Scanner(file)) { 
     while (s.hasNextLine()) { 
      String[] row = s.nextLine().split("\\s+"); 
      if (row[0].equalsIgnoreCase(name)) { 
       for (int i = 1; i < row.length; i++) { 
        data.add(Integer.parseInt(row[i])); 
       } 
      } 
     } 
    } 
    return data; 
} 

Potrebbe essere signifanctly più efficiente per eseguire la scansione del file una volta e memorizzare i nomi ei campi come Map<String, List<Integer>> come

public static Map<String, List<Integer>> readFile(String filename) { 
    Map<String, List<Integer>> map = new HashMap<>(); 
    File file = new File(System.getProperty("user.home"), filename); 
    try (Scanner s = new Scanner(file)) { 
     while (s.hasNextLine()) { 
      String[] row = s.nextLine().split("\\s+"); 
      List<Integer> al = new ArrayList<>(); 
      for (int i = 1; i < row.length; i++) { 
       al.add(Integer.parseInt(row[i])); 
      } 
      map.put(row[0], al); 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    return map; 
} 

Poi memorizzare che, come fileContents come

private Map<String, List<Integer>> fileContents = readFile(filename); 

Quindi implementa il tuo metodo loadDataFor(String) con fileContents come

public List<Integer> loadDataFor(String name) throws IOException { 
    return fileContents.get(name); 
} 

Se il modello di utilizzo legge File per molti nomi, è probabile che il secondo sia molto più veloce.

0

Se si desidera utilizzare java8 è possibile utilizzare qualcosa di simile.

Input.txt (deve essere nel classpath):

text1;4711;4712 
text2;42;43 

Il codice:

public class Main { 

    public static void main(String[] args) throws IOException, URISyntaxException { 

     // find file in classpath 
     Path path = Paths.get(ClassLoader.getSystemResource("input.txt").toURI()); 

     // find the matching line 
     findLineData(path, "text2") 

       // print each value as line to the console output 
       .forEach(System.out::println); 
    } 

    /** searches for a line in a textfile and returns the line's data */ 
    private static IntStream findLineData(Path path, String searchText) throws IOException { 

     // securely open the file in a "try" block and read all lines as stream 
     try (Stream<String> lines = Files.lines(path)) { 
      return lines 

        // split each line by a separator pattern (semicolon in this example) 
        .map(line -> line.split(";")) 

        // find the line, whiches first element matches the search criteria 
        .filter(data -> searchText.equals(data[0])) 

        // foreach match make a stream of all of the items 
        .map(data -> Arrays.stream(data) 

          // skip the first one (the string name) 
          .skip(1) 

          // parse all values from String to int 
          .mapToInt(Integer::parseInt)) 

        // return one match 
        .findAny().get(); 
     } 
    } 
} 

L'output:

42 
43 
Problemi correlati