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?
source to share
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
source to share
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
source to share
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)));
}
}
source to share
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.
source to share