Easier way to split String from .txt file in Java

Here is the code I created. It works the way I wanted, but I think it could be easier.

File test = new File("test.txt");

try{
    Scanner input = new Scanner(test);

    int[] testInt= new int[100];
    String[] test= new String[100];
    String[] print= new String[100];
    int i= 0;

    while(input.hasNextLine()){
        test[i] = input.nextLine();
        String[] temp = test[i].split(":");
        testInt[i] = Integer.parseInt(temp[1]);
        print[i] = temp[0];
        i++;
    }

    for(int j=0; j<i; j++)
        System.out.println(print[j] + ":" + testInt[j]);

} catch (FileNotFoundException ex){
    System.out.println("File not found!");
}

      

Here is the content of "test.txt":

Telur Dadar:40
Maggi Goreng:50

      

The desired result is the same as in test.txt

, except that integer values ​​are stored with the int data type. Somehow I think there is a way to do this using nextInt()

and delimiters or something. I've tried using nextInt()

some client separators as well, but all I have are a lot of errors.

Any suggestions how to do this?

+3


source to share


4 answers


I suggest you start with a subroutine to count the number of lines matched against a regex. Also you must close

a Scanner

read the file (so you don't leak files). Probably the simplest is try-with-resources

also a pattern like "^ \ D +: \ d +", which matches sequential alpha characters followed by :

consecutive digits such as

public static int countLines(File f) {
    int c = 0;
    try (Scanner s = new Scanner(f)) {
        while (s.hasNextLine()) {
            String line = s.nextLine();
            if (line.matches("^\\D+:\\d+")) {
                c++;
            }
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
    return c;
}

      

Then you can create a routine to fill the arrays (with your line Scanner

) like

public static void readLines(File f, int[] nums, String[] vals) {
    int c = 0;
    try (Scanner s = new Scanner(f)) {
        while (s.hasNextLine()) {
            String line = s.nextLine();
            if (line.matches("^\\D+:\\d+")) {
                Scanner input = new Scanner(line).useDelimiter(":");
                vals[c] = input.next();
                nums[c] = input.nextInt();
                c++;
            }
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
}

      



Finally, your method main

might look like (if test.txt

in the user's home folder) and I also recommended formatting io with printf

and renaming your variables to print

and testInt

to vals

and nums

like.

public static void main(String[] args) {
    File test = new File(System.getProperty("user.home"), "test.txt");
    int lineCount = countLines(test);
    int[] nums = new int[lineCount];
    String[] vals = new String[lineCount];
    readLines(test, nums, vals);
    for (int j = 0; j < lineCount; j++) {
        System.out.printf("%s:%d%n", vals[j], nums[j]);
    }
}

      

I get

Telur Dadar:40
Maggi Goreng:50

      

0


source


You can do it using Java 8 features as follows

package example;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;

public class SplitFile {

    public static void main(String[] args) throws IOException {
        List<Integer> numbers = new ArrayList<Integer>();
        List<String> names = new ArrayList<String>();

        try (Stream<String> stream = Files.lines(Paths.get("test.txt"))) {
            stream.forEach(s -> {
                names.add(s.split(":")[0]);
                numbers.add(Integer.parseInt((s.split(":"))[1].trim()));
            });
        }

        IntStream.range(0, Math.min(names.size(), numbers.size()))
                .mapToObj(i -> names.get(i) + ":" + numbers.get(i))
                .forEach(System.out::println);
    }

}

      



Output:

Telur Dadar:40
Maggi Goreng:50

      

+2


source


This is how you can use a map to remove arrays. This will be automatically determined by your data.

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package javaapplication2;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.HashMap; 
import java.util.Map; 
import java.util.stream.Stream;
import java.nio.file.Files;
import java.nio.file.Paths;
/**
 *
 * @author dciborow
 */
public class JavaApplication2 {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap<>();
        String file = "";        
        try (Stream<String> stream = Files.lines(Paths.get("test.txt"))) {
            stream.forEach(s -> {
                String[] split = s.split(":");
                map.put(split[0], Integer.parseInt(split[1]));
            });
        } catch (IOException ex) {
            Logger.getLogger(JavaApplication2.class.getName()).log(Level.SEVERE, null, ex);
        }

        map.keySet().stream().forEach(s -> System.out.println(s + ": " + map.get(s)));
    }
}

      

0


source


Concise, tested solution using java8

Path path = Paths.get(ClassLoader.getSystemResource("file.txt").toURI());

        Map<String, Integer> collect = Files.lines(path)
                .map(line -> line.split(":"))
                .collect(Collectors.toMap(lineArray -> lineArray[0], lineArray -> Integer.parseInt(lineArray[1])));

      

Instead, Files.lines(path)

you can use any method that provides a stream of strings (strings). The operation map

converts strings to String [] (first item = name, secont item = number). The collection uses the toMap collector, which requires two functions, one for the key, one for the value. The collector uses String [] in the previous step.

0


source







All Articles