From txt file to 2d double array in JAVA [duplicate] - java

This question already has answers here:
Reading a plain text file in Java
(31 answers)
Closed 6 years ago.
i'm working on my project in JAVA and i have .txt file that contain data like this :
3.4413 44.5444 22.793
33.3321 222.1333 44.7785
23.3001 31.1333 4.7785
77.9999 8.0001 -1.3213 3.2311
so how can i read the .txt file and convert it to :
double[0][0] = {3.4413,44.5444,22.793}
double[0][1] = {33.3321 222.1333 44.7785}
double[1][0] = {23.3001 31.1333 4.7785}
double[1][1] = {77.9999 8.0001 -1.3213 3.2311}

If you are sure that you'll be getting only 3 entities in every line then you can do something like this:
public static void main (String[] args)
{
double[][] arr = new double[10][3];
int ptr = 0;
Scanner in = new Scanner(System.in);
while(in.hasNext()) {
arr[ptr][0] = in.nextDouble();
arr[ptr][1] = in.hasNext() ? in.nextDouble() : 0d;
arr[ptr++][2] = in.hasNext() ? in.nextDouble() : 0d;
}
}
Please note that here I have used Scanner and am taking input from System.in. You can replace it to take input from your file.
Considering the above input this will result in the following output:
arr[0][0] -> 3.4413
arr[0][1] -> 44.5444
arr[0][2] -> 22.793
For the first row and so on.

Related

Java: getting an index out of bounds exception

Background
Building an Assembler in Java:
I'm trying to read user's input into an ArrayList named v.
If the user enters an instruction that matches one of the String-array table, then the corresponding opcode will be calculated and output into a textfile.
Problem
However, after inputting the nop instruction and trying to add another instruction, I got an index out of bounds exception.
Source Code
//Array of instructions
String table[] = {"LI", " MALSI", "MAHSI", "MSLSI", "MSHSI", "MALSL", "MAHSL",
"MSLSL", "MSHSL", "NOP", "A", "AH", "AHS", "AND", "BCW", "CLZ", "MAX", "MIN",
"MSGN", "MPYU", "OR", "POPCNTH", "ROT", "ROTW", "SHLHI", "SFH", "SFW", "SFHS", "XOR "};
//Array of binary values of the instructions
String table2[] = {"0", "10000", "10001", "10010", "10011", "10100", "10101",
"10110", "10111", "1100000000000000000000000", "1100000001", "1100000010", "1100000011",
"1100000100", "1100000101", "1100000110", "1100000111", "1100001000", "1100001001",
"1100001010", "1100001011", "1100001100", "1100001101", "1100001110", "1100001111",
"1100010000", "1100010001", "1100010010", "1100010011"};
// TODO code application logic here
Scanner s = new Scanner(System.in);
String ins = "";
String fileName = "outfile.txt";
System.out.println("Please enter MISP function, enter Q to Quit: ");
boolean q = true;
String op = "";
int c = 0;
String array[] = new String[64];
//Loop to keep accepting userinput
while (q) {
//accepts the user input
ins = s.nextLine();
//arraylist to hold user input
List<String> v = new ArrayList<String>();
//adds the user input to the arraylist
v.add(ins);//user input to nop opcode
if (v.get(0).toUpperCase().equals("NOP")) {
op = "1100000000000000000000000";
} else if (v.get(1).toUpperCase().equals("LI"))//li opcode
{
String p[] = v[1].split(",", 1);
op = "0";
op += toBinary(p[0], 3);
op += toBinary(p[1], 16);
op += toBinary(p[2], 5);
Error Stacktrace I got
Exception in thread "main" java.lang.IndexOutOfBoundsException:
If you guys could help it would be appreciated.
This loop will never end.
while (q)

how to group 59 elements into one element in arraylist?

so, i have a program that read value and its year from a textfile that starts from 1960 till 2018. each indicator code have different values but the year stays the same, 1960-2018. i have successfully read the textfile and store it in the arraylist.
however, values and its years from one indicator is not grouped in one element. but instead, it groups them one value(and its year), one element. AND let's say i have 2 indicator code, 59 values for each indicator code. they're all mixed up in 118 elements. i wanted them in 2 elements.
how to solve this problem so that each indicator code and its data(years and values) is in one element?
myLinkedList bigdata = new myLinkedList();
ArrayList <MyData> data = new ArrayList();
MyData d1;
File inFile2 = new File ("indicator2.txt");
FileReader fr2 = new FileReader (inFile2);
BufferedReader br2 = new BufferedReader(fr2);
String str2 = br2.readLine();
while(str2 != null ){
StringTokenizer st = new StringTokenizer(str2,";");
String cCode = st.nextToken();
String iName = st.nextToken();
String iCode = st.nextToken();
for (int j = 0; j < 59; j++){
String v = st.nextToken();
int year = 1960 + j;
d1 = new MyData (year,v);
data.add(d1);
}
Indicator idct1 = new Indicator (cCode,iName,iCode,data);
bigdata.insertAtBack(idct1);
str2 = br2.readLine();
}
example of indicator2.txt:
MYS; Employment in industry (% of total employment) (modeled ILO estimate); SL.IND.EMPL.ZS; null;null;null;null;null;null;null;null;null;null;null;null;null;null;null;null;null;null;null;null;null;null;null;null;null;null;null;null;null;null;null;31,72100067;31,62000084;32,01699829;32,22900009;32,34000015;32,23300171;33,6629982;31,76000023;31,70000076;32,18299866;33,11000061;31,97999954;32,02000046;30,12700081;29,72299957;30,26000023;28,45999908;28,68000031;27,01300049;27,73699951;29,08600044;28,56900024;28,36300087;28,02300072;27,51600075;27,48699951;27,39800072;27,30500031
(From left: cCode; iName; iCode; the values starting from 1960)
I believe the problem is that you're writing the data into the same ArrayList over and over again for all indicator codes. What if you moved the following statement:
ArrayList <MyData> data = new ArrayList();
Inside your while loop. Then you would be creating a new ArrayList for each indicator code when your save it to an Indicator object.
Generic types can be nested, so one solution would be to use an ArrayList of ArrayLists of MyData objects instead:
ArrayList<ArrayList<MyData>>

Parse string to float/double [duplicate]

This question already has answers here:
How do I convert a String to Double in Java using a specific locale?
(8 answers)
Closed 3 years ago.
I am getting values from jTable and putting it in my DataBase (MySQL). In my DB table there is column PAYMENT that is double. When I try to put values from my jTable there is a problem with it:
String payment=(String) jTable1.getValueAt(row, 2);
double pay=double .parseDouble (payment);
........
pst.setDouble(3, zar);
I am getting this exception:
Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: For input string: "84,21834324"
How can I put this column from jTable as double in my DB table?
P.S.: I tried with float too.
Replace your , with a .:
String payment = (String) jTable1.getValueAt(row, 2);
double pay = Double.parseDouble(payment.replace(",". "."));
........
pst.setDouble(3, zar);
Edit -- If you want to support more complex values:
import java.util.Locale;
import java.text.*;
class Main {
public static void main(String[] args) throws ParseException {
String v1 = "84,21834324";
String v2 = "1.234.567,89";
NumberFormat format = NumberFormat.getInstance(Locale.ENGLISH);
Number n1 = format.parse(v1);
Number n2 = format.parse(v2);
double d1 = n1.doubleValue();
double d2 = n2.doubleValue();
}
}
Lifted the edited solution from this question

How to parse my log.txt in this format in java

I am trying to parse this certain log entry
"[Zone] ZoneChangeList.ProcessChanges() - processing index=9
change=powerTask=[power=[type=TAG_CHANGE entity=[id=78 cardId=FP1_007t
name=Nerubian] tag=IGNORE_DAMAGE_OFF value=1] complete=False]
entity=[name=Nerubian id=78 zone=GRAVEYARD zonePos=1 cardId=FP1_007t
player=2] srcZoneTag=INVALID srcPos= dstZoneTag=INVALID dstPos=";
I am using a scanner delimiter in Java but the problem is that the change field
which has multiple values enclosed in a bracket.
I would also want to put the parsed record on a bean having their values
So far, here is what I have coded:
public class HearthstoneParser {
public void zoneParser(String line) {
Scanner scanner = new Scanner(line);
scanner.useDelimiter(" ");
while (scanner.hasNext()) {
System.out.println(scanner.next());
}
}
public static void main(String args[]) {
String zoneString = "[Zone] ZoneChangeList.ProcessChanges() - processing index=9 change=powerTask=[power=[type=TAG_CHANGE entity=[id=78 cardId=FP1_007t name=Nerubian] tag=IGNORE_DAMAGE_OFF value=1] complete=False] entity=[name=Nerubian id=78 zone=GRAVEYARD zonePos=1 cardId=FP1_007t player=2] srcZoneTag=INVALID srcPos= dstZoneTag=INVALID dstPos=";
HearthstoneParser parser = new HearthstoneParser();
parser.zoneParser(zoneString);
}
}
I would want to keep them organized that they are group with their brackets respectively
sample output would be:
Zone
event = ZoneChangeList.ProcessChanges()
index = 9
change
powerTask
power
type = TAG_CHANGE
entity
id = 78
cardID=Fp1_007t
name Nerubian
tag=IGNORE_DAMAGE_OFF
value=1
complete=False
entity
name=nerubian
id=78
zone=GRAVEYARD
zonePos=1
cardId=FP1_007t
player=2
srcZoneTag=INVALID
srcPos=
dstZoneTag=INVALID
dstPos=

Extracting data from a collection in Java

I have a csv dataset like this:
A, 10, USA
B,30, UK
C,4,IT
A,20,UK
B,10,USA
I want to read this csv lines and provide the following output:
A has ran 30 miles with average of 15.
B has ran 30 miles with average of 20.
C has ran 4 miles with average of 4.
I want to achieve this in Java. I have done this in C# by using Linq:
var readlines = File.ReadAllLines(filename);
var query = from lines in readlines
let data = lines.Split(',')
select new
{
Name = data[0],
Miles = data[1],
};
var values = query.GroupBy(x => new {x.Name}).Select(group => new { Person = group.Key, Events = group.Sum(g =>Convert.ToDouble(g.Miles)) ,Count = group.Count() });
I am looking to do this in Java, and I am not sure if I can do this without using any third party library or not? Any ideas?
So far, my code looks like this in Java:
CSVReader reader = new CSVReader(new FileReader(filename));
java.util.List<String[]> content = reader.readAll();
String[] row = null;
for(Object object:content)
{
row = (String[]) object;
String Name = row[0];
String Miles = row[1];
System.out.printf("%s has ran %s miles %n",Name,Miles);
}
reader.close();
}
I am looking for a nice way to get the total milage value for each name to calculate for the average.
As a C# developer, it is hard sometimes not to miss the features of linq. But as Farlan suggested you could do something like this:
CSVReader reader = new CSVReader(new FileReader(filename));
java.util.List<String[]> content = reader.readAll();
Map<String, Group> groups = new HashMap<>();
for(String[] row : content)
{
String Name = row[0];
String Miles = row[1];
System.out.printf("%s has ran %s miles %n", Name, Miles);
if (groups.containsKey(Name)){
groups.get(Name).Add(Double.valueOf(Miles));
} else {
Group g = new Group();
g.Add(Double.valueOf(Miles));
groups.put(Name, g);
}
}
reader.close();
for (String name : groups.keySet())
{
System.out.println(name + " ran " + groups.get(name).total() + " with avg of " + groups.get(name).average());
}
}
class Group {
private List<Double> miles;
public Group()
{
miles = new ArrayList<>();
}
public Double total(){
double sum = 0;
for (Double mile : miles)
{
sum += mile;
}
return sum;
}
public Double average(){
if (miles.size() == 0)
return 0d;
return total() / miles.size();
}
public void Add(Double m){
miles.add(m);
}
}
Use Java's BufferedReader class:
BufferedReader in = new BufferedReader(new FileReader("your.csv"));
String line;
while ( (line = in.readLine()) != null) {
String [] fields = line.split(",");
System.out.println(fields[0] + " has ran " + fields[1] + " miles with average " + fields[2]);
}
There are quite a few ways to do this, some long-winded approaches, some shorter. The issue is that Java can be very verbose for doing simple tasks, so the better approaches can be a bit uglier.
The example below shows you exactly how to achieve this, par the printing. Bear in mind however, it might not be the best approach but I feel its more of the easier ones to read and comprehend.
final File csvFile = new File("filename.csv");
final Scanner reader = new Scanner(csvFile);
final Map<String, Integer> info = new HashMap<>(); //Store the data
//Until there is are no more lines, continue
while (reader.hasNextLine()) {
final String[] data = reader.nextLine().split(","); // data[0] = A. [1] = 10. [2] = USA
final String alpha = data[0];
if (!info.containsKey(alpha)) {
info.put(alpha, Integer.parseInt(data[1]));
} else {
int miles = info.get(alpha);
info.put(alpha, miles + Integer.parseInt(data[1]));
}
}
reader.close();
The steps involved are simple:
Step 1 - Read the file.
By passing a File into the Scanner object, you set the target parsing to the File and not the console. Using the very neat hasNextLine() method, you can continually read each line until no more exist. Each line is then split by a comma, and stored in a String array for reference.
Step 2 - Associating the data.
As you want to cumulatively add the integers together, you need a way to associate already passed in letters with the numbers. A heavyweight but clean way of doing this is to use a HashMap. The Key which it takes is going to be a String, specifically A B or C. By taking advantage of the fact the Key is unique, we can use the O(1) containsKey(String) method to check if we've already read in the letter. If its new, add it to the HashMap and save the number with it. If however, the letter has been seen before, we find the old value, add it with the new one and overwrite the data inside the HashMap.
All you need to do now is print out the data. Feel free to take a different approach, but I hope this is a clear example of how you CAN do it in Java.
Maybe you could try this Java library: https://code.google.com/p/qood/
It handles data without any getter/setters, so it's more flexible than LINQ.
in your case, file "D:/input.csv" has 3 columns:
NAME,MILES,COUNTRY
A, 10, USA
B,30, UK
C,4,IT
A,20,UK
B,10,USA
the query code would be:
final QModel raw = QNew.modelCSV("D:/input.csv")
.debug(-1);//print out what read from CSV
raw.query()
.selectAs("OUTPUT",
"CONCAT(NAME,' has ran ',SUM(MILES),' miles with average of ',MEAN(MILES),'.')")
.groupBy("NAME")
.result().debug(-1)//print out the result
.to().fileCSV("D:/output.csv", "UTF-8");//write to another CSV file

Categories

Resources