Convert a .txt file with doubles to an ArrayList - java

I have a .txt file with this content: "17.23;12.1;20.34;88.23523;".
I want to read this file as doubles into an ArrayList. And eventually print the ArrayList (and eventually print the min. and max., but I don't think that will be a problem after solving this).
But I only get the output "[ ]".
What am I doing wrong? I've been struggling with this for embarrassing 15+ hours, browsed here, youtube, course books...
My code:
public static void main(String[] args) throws IOException {
File myFile = new File("text.txt");
Scanner scan = new Scanner(myFile);
ArrayList<Double> aList = new ArrayList<>();
while (scan.hasNextDouble()) {
double nextInput = scan.nextDouble();
if (nextInput != 0) {
break;
}
aList.add(nextInput);
}
System.out.println(alist);
}

You should configure your scanner so it will accept:
; as a delimiter
, as a decimal separator
Working code is:
File myFile = new File("input.txt");
// Swedish locale uses ',' as a decimal separator
Scanner scan = new Scanner(myFile).useDelimiter(";").useLocale(Locale.forLanguageTag("sv-SE"));
ArrayList<Double> aList = new ArrayList<>();
while (scan.hasNextDouble()) {
double nextInput = scan.nextDouble();
aList.add(nextInput);
}
System.out.println(aList);
With output [17.23, 12.1, 20.34, 88.23523]

Scanner works by splitting the input into tokens, where tokens are separated by whitespaces (by default). Since there are no whitespaces in the text, the first/only token is the entire text, and since that text is not a valid double value, hasNextDouble() returns false.
Two ways to fix that:
Change the token separator to ;:
scan.useDelimiter(";");
Read the file with BufferedReader and use split():
String filename = "text.txt";
try (BufferedReader in = Files.newBufferedReader(Paths.get(filename))) {
for (String line; (line = in.readLine()) != null; ) {
String[] tokens = line.split(";");
// code here
}
}
That will now result in the following tokens: 17,23, 12,1, 20,34, 88,23523.
Unfortunately, none of those are valid double values, because they use locale-specific formatting, i.e. the decimal point is a ,, not a ..
Which means that if you kept using Scanner, you can't use hasNextDouble() and nextDouble(), and if you changed to use split(), you can't use Double.parseDouble().
You need to use a NumberFormat to parse locale-specific number formats. Since "Uppgift" looks Swedish, we can use NumberFormat.getInstance(Locale.forLanguageTag("sv-SE")), or simply NumberFormat.getInstance() if your default locale is Sweden.
String filename = "text.txt";
try (BufferedReader in = Files.newBufferedReader(Paths.get(filename))) {
NumberFormat format = NumberFormat.getInstance(Locale.forLanguageTag("sv-SE"));
for (String line; (line = in.readLine()) != null; ) {
List<Double> aList = new ArrayList<>();
for (String token : line.split(";")) {
double value = format.parse(token).doubleValue();
aList.add(value);
}
System.out.println(aList); // Prints: [17.23, 12.1, 20.34, 88.23523]
}
}

You can do it simply by changing the delimiter. This works by reading from a String but you can also do it from a file. It is up to you to put the values in some data structure. This presumes your default locale uses ',' as a decimal point.
String str = "17,23;12,1;20,34;88,23523;";
Scanner scan = new Scanner(str);
scan.useDelimiter("[;]+");
while(scan.hasNextDouble()) {
System.out.println(scan.nextDouble());
}
prints
17.23
12.1
20.34
88.23523

Since your file has numbers separated by a semi-colon, you won't be able to read them using scan.hasNextDouble() by default. However, there are so many ways of doing it e.g.
Override the default delimiter.
Reading a line as string and process each number from it after splitting it on the semi-colon.
Option-1:
scan.useDelimiter(";")
Note that since your file has the comma instead of the dot as the decimal symbol, you can use a Locale in which it is the default.
scan.useLocale(Locale.FRANCE);
Also, the following code block in your code will cause the loop to be terminated after reading the first number itself as the first number in your file in not equal to zero. Simply remove these lines in order to get the desired result:
if (nextInput != 0) {
break;
}
Option-2:
Read a line, split it on a semi-colon, replace the comma with a dot, parse each element from the resulting array into Double and store the same into aList.
Demo:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws FileNotFoundException {
File myFile = new File("file.txt");
Scanner scan = new Scanner(myFile);
List<Double> aList = new ArrayList<>();
while (scan.hasNextLine()) {
String nextInput = scan.nextLine();
String[] arr = nextInput.split(";");
for (String s : arr) {
aList.add(Double.valueOf(s.replace(",", ".")));
}
}
System.out.println(aList);
}
}
Output:
[17.23, 12.1, 20.34, 88.23523]
An alternative to replace comma with dot is to use NumberFormat as shown below:
import java.io.File;
import java.io.FileNotFoundException;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws FileNotFoundException, ParseException {
File myFile = new File("file.txt");
Scanner scan = new Scanner(myFile);
NumberFormat format = NumberFormat.getInstance(Locale.FRANCE);
List<Double> aList = new ArrayList<>();
while (scan.hasNextLine()) {
String nextInput = scan.nextLine();
String[] arr = nextInput.split(";");
for (String s : arr) {
aList.add(format.parse(s).doubleValue());
}
}
System.out.println(aList);
}
}

Related

How to correctly identify words when reading from a file with java Scanner?

I'm trying to do an exercise where I need to create a class to read the words from a .txt put the words in an HashSet. The thing is, if the text read "I am Daniel, Daniel I am." I'll have a word for "am" , "am." and "Daniel," and "Daniel". How do I fix this?
Here's my code. (I tried to use regex, but I'm getting an exception):
import java.io.File;
import java.io.FileNotFoundException;
import java.util.HashSet;
import java.util.Scanner;
public class WordCount {
public static void main(String[] args) {
try {
File file = new File(args[0]);
HashSet<String> set = readFromFile(file);
set.forEach(word -> System.out.println(word));
}
catch(FileNotFoundException e) {
System.err.println("File Not Found!");
}
}
private static HashSet<String> readFromFile(File file) throws FileNotFoundException {
HashSet<String> set = new HashSet<String>();
Scanner scanner = new Scanner(file);
while(scanner.hasNext()) {
String s = scanner.next("[a-zA-Z]");
set.add(s.toUpperCase());
}
scanner.close();
return set;
}
}
Error is thrown when the Scanner try to read a string not matching with the regex.
String s = scanner.next("[a-zA-Z]");
Instead of passing the regex in the Scanner. Read the word and remove the special characters as shown below.
String s = scanner.next();
s = s.replaceAll("[^a-zA-Z]", "");

Java reading a file into a list

I need to figure out a way to turn an input file into a list of sentences which are delimited by more than one character, or more specifically, periods and exclamation points (! or .)
My input file has a layout similar to this:
Sample textfile!
A man, l, a ballot, a catnip, a pooh, a rail, a calamus, a dairyman, a bater, a canal - Panama!
This is a sentence! This one also.
Heres another one?
Yes another one.
How can I put that file into a list sentence by sentence?
Each sentence in my file is finished once a ! or . character is passed.
There are a decent amount of ways to accomplish what you are asking, but here is one way to read a file into a program and split each line by specific delimiters into a list, while still keeping the delimiters in the sentence.
All of the functionality for turning a file to a list based on multiple delimiters can be found in the turnSentencesToList() method
In my example below I split by: ! . ?
import java.io.File;
import java.io.FileNotFoundException;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test{
public static void main(String [] args){
LinkedList<String> list = turnSentencesToList("sampleFile.txt");
for(String s: list)
System.out.println(s);
}
private static LinkedList<String> turnSentencesToList(String fileName) {
LinkedList<String> list = new LinkedList<>();
String regex = "\\.|!|\\?";
File file = new File(fileName);
Scanner scan = null;
try {
scan = new Scanner(file);
while(scan.hasNextLine()){
String line = scan.nextLine().trim();
String[] sentences = null;
//we don't need empty lines
if(!line.equals("")) {
//splits by . or ! or ?
sentences = line.split("\\.|!|\\?");
//gather delims because split() removes them
List<String> delims = getDelimiters(line, regex);
if(sentences!=null) {
int count = 0;
for(String s: sentences) {
list.add(s.trim()+delims.get(count));
count++;
}
}
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}finally {
if(scan!=null)
scan.close();
}
return list;
}
private static List<String> getDelimiters(String line, String regex) {
//this method is used to provide a list of all found delimiters in a line
List<String> allDelims = new LinkedList<String>();
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(line);
String delim = null;
while(matcher.find()) {
delim = matcher.group();
allDelims.add(delim);
}
return allDelims;
}
}
Based on your example input file, the produced output would be:
Sample textfile!
A man, l, a ballot, a catnip, a pooh, a rail, a calamus, a dairyman, a bater, a canal - Panama!
This is a sentence!
This one also.
Heres another one?
Yes another one.

parsing CSV file in Java with skipping the next row if is the first field is empty

I am using Java, and I have a CSV file that consists of 10 column and 5 rows. I would like to parse it into another CSV file with the this condition. if the first cell from any row is empty, skip that row, and jump to the next and so on. My code only reads all the rows and prints them, I want to have that condition and write into another CSV file.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class CSV {
public static void main(String[] args) throws FileNotFoundException {
String x;
Scanner scanner = new Scanner(new File("Book1.csv"));
scanner.useDelimiter(",");
while(scanner.hasNext()){
System.out.print(scanner.next());
}
scanner.close();
}
}
Example:
see the attached image please.
Instead of delimiting the whole file, delimit line by line:
public static void main(String[] args) throws FileNotFoundException {
String x;
Scanner scanner = new Scanner(new File("Book1.csv"));
while(scanner.hasNextLine()){ // If there is another line in the file
x = scanner.nextLine(); // Extract that line
String[] values = x.split(","); // Split that line at the commas
if (!values[0].equals("")) { // If the first value is not equal to empty
System.out.print(x); // Print the line
}
}
scanner.close();
}
You can take advantage of the fact that each record is a different line. So, instead of using Scanner class directly over the File, you can retrieve full lines with BufferedReader#readLine():
BufferedReader br = new BufferedReader(new FileReader("Book1.csv"));
String myLine = br.readLine();
while (myLine != null) {
// do whatever you want with the line
// read new line
myLine = br.readLine();
}
So that myLine contains Strings like the following:
"John,M,Mi,1111,US,OR,..."
",David,criss,2222,US,MI,..."
Once you have a line, trim() it and check if the first character is your delimiter. In that case, the line should be ignored.
myLine = myLine.trim();
if (",".equals(myLine.at(0))) {
// First field empty. Ignore
} else {
// First field not empty. Write to new file
}

Adding data from .txt document to array

Below is what the text document looks like. The first line is the number of elements that I want the array to contain. The second is the ID for the product, separated by # and the third line is the total price of the products once again separated by #
10
PA/1234#PV/5732#Au/9271#DT/9489#HY/7195#ZR/7413#bT/4674#LR/4992#Xk/8536#kD/9767#
153#25#172#95#235#159#725#629#112#559#
I want to use the following method to pass inputFile to the readProductDataFile method:
public static Product[] readProductDataFile(File inputFile){
// Code here
}
I want to create an array of size 10, or maybe an arrayList. Preferably to be a concatenation of Customer ID and the price, such as Array[1] = PA/1234_153
There you go the full class, does exactly what you want:
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.Arrays;
import java.io.FileNotFoundException;
import java.io.IOException;
class myRead{
public static void main(String[] args) throws FileNotFoundException, IOException {
BufferedReader inputFile = new BufferedReader(new FileReader("test.txt"));
String numberOfElements = inputFile.readLine();
//this is the first line which contains the number "10"
//System.out.println(numberOfElements);
String secondLine = inputFile.readLine();
//this is the second line which contains your data, split it using "#" as a delimiter
String[] strArray = secondLine.split("#");
//System.out.println(Arrays.toString(strArray));
//System.out.println(strArray[0]);
String thirdLine = inputFile.readLine();
//this is the third line which contains your data, split it using "#" as a delimiter
String[] dataArray = thirdLine.split("#");
//combine arrays
String[] combinedArray = new String[strArray.length];
for (int i=0;i<strArray.length;i++) {
combinedArray[i]=strArray[i]+"_"+dataArray[i];
System.out.println(combinedArray[i]);
}
}
}
OUTPUT:
PA/1234_153
PV/5732_25
Au/9271_172
DT/9489_95
HY/7195_235
ZR/7413_159
bT/4674_725
LR/4992_629
Xk/8536_112
kD/9767_559
The trick in what I am doing is using a BufferedReader to read the file, readLine to read each of the three lines, split("#"); to split each token using the # as the delimiter and create the arrays, and combinedArray[i]=strArray[i]+"_"+dataArray[i]; to put the elements in a combined array as you want...!
public static Product[] readProductDataFile(File inputFile){
BufferedReader inputFile = new BufferedReader(new FileReader(inputFile));
// the rest of my previous code goes here
EDIT: Everything together with calling a separate method from inside the main, with the file as an input argument!
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.Arrays;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.File;
class myRead{
public static void main(String[] args) throws FileNotFoundException, IOException {
File myFile = new File("test.txt");
readProductDataFile(myFile);
}
public static String[] readProductDataFile(File inputFile) throws FileNotFoundException, IOException{
BufferedReader myReader = new BufferedReader(new FileReader("test.txt"));
String numberOfElements = myReader.readLine();
//this is the first line which contains the number "10"
//System.out.println(numberOfElements);
String secondLine = myReader.readLine();
//this is the second line which contains your data, split it using "#" as a delimiter
String[] strArray = secondLine.split("#");
//System.out.println(Arrays.toString(strArray));
//System.out.println(strArray[0]);
String thirdLine = myReader.readLine();
//this is the third line which contains your data, split it using "#" as a delimiter
String[] dataArray = thirdLine.split("#");
//combine arrays
String[] combinedArray = new String[strArray.length];
for (int i=0;i<strArray.length;i++) {
combinedArray[i]=strArray[i]+"_"+dataArray[i];
System.out.println(combinedArray[i]);
}
return combinedArray;
}
}
OUTPUT
PA/1234_153
PV/5732_25
Au/9271_172
DT/9489_95
HY/7195_235
ZR/7413_159
bT/4674_725
LR/4992_629
Xk/8536_112
kD/9767_559
You don't even need the first line. Just read the second line directly into a single string and then split it by using String,split() method.
Read more for split method here.
You could use something like this (Be aware that i can't test it at the moment)
BufferedReader in = null;
try {
in = new BufferedReader(new FileReader("fileeditor.txt"));
String read = null;
String firstLine=in.readLine();
//reads the first line
while ((read = in.readLine()) != null) {
// reads all the other lines
read = in.readLine();
String[] splited = read.split("#");
//split the readed row with the "#" character
for (String part : splited) {
System.out.println(part);
}
}
} catch (IOException e) {
System.out.println("There was a problem: " + e);
e.printStackTrace();
} finally {
try {
//close file
in.close();
} catch (Exception e) {
}
}
This is how you can do it using Java (don't forget to import):
public static Product[] readProductDataFile(File inputFile){
Scanner s = new Scanner(inputFile);
String data = "";
while(s.hasNext())
data += s.nextLine();
String[] dataArray = data.split("#");
}
You can try this way ..
Reading line by line and storing each row in a array.
Use while storing so it will split and save .
String[] strArray = secondLine.split("#");
Now use the for loop and concat the values as u wish and save ina third array .
For(int i=0 ;i< file.readline;i++)
{
string s = a[customerid];
s.concat(a[productid]);
a[k] =s;
}

Read each line in a text file for strings, doubles, and ints an place them in different arrays

this is my first question here so I hope I'm doing this right. I have a programming project that needs to read each line of a tab delimited text file and extract a string, double values, and int values. I'm trying to place these into separate arrays so that I can use them as parameters. This is what I have so far(aside from my methods):
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Scanner;
public class LoanDriver {
public static void main(String[] args)
{
String[] stringData = new String[9];
Scanner strings = null;
try
{
FileReader read = new FileReader("amounts.txt");//Read text file.
strings = new Scanner(read);
String skip = strings.nextLine();//Skip the first line by storing it in an uncalled variable
strings.useDelimiter("\t *");//Tab delimited
}
catch (FileNotFoundException error)
{}
while (strings.hasNext())
{
String readLine = strings.next();
stringData = readLine.split("\t");
}
}}
If I try to get the [0] value, it skips all the way to the bottom of the file and returns that value, so it works to some extent, but not from the top like it should. Also, I can't incorporate arrays into it because I always get an error that String[] and String is a type mismatch.
Instead of using delimiter, try reading the file line by line using Scanner.nextLine and split each new line you read using String.split ("\t" as argument).
try {
FileReader read = new FileReader("amounts.txt");//Read text file.
strings = new Scanner(read);
String skip = strings.nextLine();//Skip the first line by storing it in an uncalled variable
}
catch (FileNotFoundException error) { }
String line;
while ((line = strings.nextLine()) != null) {
String[] parts = line.split("\t");
//...
}
You are getting the last value in the file when you grab stringData[0] because you overwrite stringData each time you go through the while loop. So the last value is the only one present in the array at the end. Try this instead:
List<String> values = new ArrayList<String>();
while (strings.hasNext()) {
values.add(strings.next());
}
stringData = values.toArray(new String[values.size()]);

Categories