TSV file into 2d array - java - java

I have a tsv txt file containing data in 3 rows.
It looks like:
HG sn FA
PC 2 16:0
PI 1 18:0
PS 3 20:0
PE 2 24:0
26:0
16:1
18:2
I want to read this file into a 2 dimensional array in java.
But i get an error all the time, no matter what i try.
File file = new File("table.txt");
Scanner scanner = new Scanner(file);
final int maxLines = 100;
String[][] resultArray = new String[maxLines][];
int linesCounter = 0;
while (scanner.hasNextLine() && linesCounter < maxLines) {
resultArray[linesCounter] = scanner.nextLine().split("\t");
linesCounter++;
}
System.out.print(resultArray[1][1]);
I keep getting this error
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
at exercise.exercise2.main(exercise2.java:31)
Line 31 is
System.out.print(resultArray[1][1]);
I cannot find any reasons why this error keeps emerging

In your case I would use Java 7 Files.readAllLines.
Something like:
String[][] resultArray;
List<String> lines = Files.readAllLines(Paths.get("table.txt"), StandardCharsets.UTF_8);
//lines.removeAll(Arrays.asList("", null)); // <- remove empty lines
resultArray = new String[lines.size()][];
for(int i =0; i<lines.size(); i++){
resultArray[i] = lines.get(i).split("\t"); //tab-separated
}
Output:
[[HG, sn FA ], [PC, 2, 16:0], [PI, 1, 18:0], [PS, 3, 20:0], [PE, 2, 24:0], [, , 26:0], [, , 16:1], [, , 18:2]]
And this is the file (press edit and grab the content, it should be tab separated):
HG sn FA
PC 2 16:0
PI 1 18:0
PS 3 20:0
PE 2 24:0
26:0
16:1
18:2
[EDIT]
To get 16:1:
System.out.println(root[6][2]);

Related

How to create Strings from a JTable txt file?

I need to read from a txt file and sort everything in different arrays or strings, allowing me to set text for my JLabels. One array/string for ID, Item Name, Price and Stock.
This is a preview of my txt file:
Here is my code to read the txt file to import it to my JTable:
String filePath = "C:\\Users\\zagad\\IdeaProjects\\DATABYTES\\stock\\consoles\\consoles.txt";
File file = new File(filePath);
try {
BufferedReader br = new BufferedReader(new FileReader(file));
String firstLine = br.readLine().trim();
String[] columnsName = firstLine.split(", ");
DefaultTableModel model3 = (DefaultTableModel) productTable.getModel();
model3.setColumnIdentifiers(columnsName);
Object[] tableLines = br.lines().toArray();
for (int i = 0; i < tableLines.length; i++) {
String line = tableLines[i].toString().trim();
String[] dataRow = line.split("/");
model3.addRow(dataRow);
}
} catch (IOException ex) {
ex.printStackTrace();
}
How do I separate them? Any help would be appreciated.
TXT FILE:
ID , Item Name ,Price , Stock
00016 / Apple Airpods / 8999 / 20
00017 / Samsung Galaxy Buds / 6999 / 13
00018 / Apple Airpods Pro / 14999 / 5
00019 / Beats Powerbeats Pro / 13490 / 8
00020 / Sony WF-1000XM3 / 10799 / 10
It appears that the format separates each of the columns by \ so you can split the String by that. What we can do is read all lines from a given Path object which is the Path to the file. We can then skip the first line which we know is the table column names. We can then map each of these lines which are individual String objects to a String array by removing all whitespace with the replaceAll reference and then use the String#split method to split the line by \ which will give us each of the columns for each row. We can then collect all of these String arrays to a List using the Stream#collect method.
List<String> lines = Files.readAllLines(Paths.get("first.txt"));
String[] columnNames = lines.stream().findFirst().orElseThrow(IOException::new).split(",");
List<MyRow> rows = lines
.stream()
.skip(1)
.map(line -> line.replaceAll(" ", "").split("/"))
.map(MyRow::valueOf)
.collect(Collectors.toList());
DefaultTableModel model3 = new DefaultTableModel();
model3.setColumnIdentifiers(columnNames);
rows.forEach(row -> model3.addRow(new Object[] { row.getId(), row.getItemName(), row.getPrice(), row.getStock() }));
List<Integer> ids = rows.stream().map(MyRow::getId).collect(Collectors.toList());
Output:
[00016, AppleAirpods, 8999, 20]
[00017, SamsungGalaxyBuds, 6999, 13]
[00018, AppleAirpodsPro, 14999, 5]
[00019, BeatsPowerbeatsPro, 13490, 8]
[00020, SonyWF-1000XM3, 10799, 10]

Trouble with scanner, cant manage to read in TSP-file

I'm currently trying to read in coordinates from a TSP-file, they usually look something like this:
NAME: berlin52
TYPE: TSP
COMMENT: 52 locations in Berlin (Groetschel)
DIMENSION: 52
EDGE_WEIGHT_TYPE: EUC_2D
NODE_COORD_SECTION
1 565.0 575.0
2 25.0 185.0
3 345.0 750.0
4 945.0 685.0
5 845.0 655.0
6 880.0 660.0
7 25.0 230.0
8 525.0 1000.0
9 580.0 1175.0
10 650.0 1130.0
11 1605.0 620.0
12 1220.0 580.0
13 1465.0 200.0
14 1530.0 5.0
15 845.0 680.0
16 725.0 370.0
17 145.0 665.0
18 415.0 635.0
19 510.0 875.0
20 560.0 365.0
21 300.0 465.0
22 520.0 585.0
23 480.0 415.0
24 835.0 625.0
25 975.0 580.0
26 1215.0 245.0
27 1320.0 315.0
28 1250.0 400.0
29 660.0 180.0
30 410.0 250.0
31 420.0 555.0
32 575.0 665.0
33 1150.0 1160.0
34 700.0 580.0
35 685.0 595.0
36 685.0 610.0
37 770.0 610.0
38 795.0 645.0
39 720.0 635.0
40 760.0 650.0
41 475.0 960.0
42 95.0 260.0
43 875.0 920.0
44 700.0 500.0
45 555.0 815.0
46 830.0 485.0
47 1170.0 65.0
48 830.0 610.0
49 605.0 625.0
50 595.0 360.0
51 1340.0 725.0
52 1740.0 245.0
EOF
What I want to do is to read all the nodes, their two coordinates and create a node from this. I would like to store them in an arraylist storing lists, like:
ArrayList<String[]>
My code is currently looking like this:
package group12.TSP.tree;
import java.io.File;
import java.util.*;
public class Tree {
ArrayList<String[]> storing = new ArrayList<String[]>();
public Tree() throws Exception{
File file = new File("C:/Users/joaki/Desktop/burma14.tsp");
Scanner sc = new Scanner(file);
storing = new ArrayList<String[]>();
String nextValue = null;
//sc.reset();
sc.useDelimiter(" ");
while (sc.hasNextLine()) {
sc.nextLine();
while(sc.hasNextDouble()) {
nextValue = sc.nextLine();
//st.replaceAll("\\s+","")
//nextValue = nextValue.replace(" ", "");
storing.add(nextValue.split(""));
continue;
}
}
sc.close();
}
public static ArrayList<String[]> returnScanner() throws Exception {
Tree tree = new Tree();
return tree.storing;
}
public static void main(String[] args) throws Exception{
ArrayList<String[]> storedValues = returnScanner();
String[] firstLine = storedValues.get(0);
String[] secondLine = storedValues.get(1);
for(int i = 0; i < firstLine.length; i++) {
System.out.println(firstLine[i]);
}
}
}
This doesnt make the things I want it to do, but I dont understand how to implement it, I guess it could just copy the coordinates to a text-file but I want it to work for all sorts of TSPS. Thanks in advance!
made a few changes here. I read up to "NODE_COORD_SECION" then start parsing ans storing the lines. Instead of splitting on "" I split on " " and store the values.
public class Tree {
ArrayList<String[]> storing;
public Tree() throws Exception {
File file = new File("C:/Users/joaki/Desktop/burma14.tsp");
Scanner sc = new Scanner(file);
storing = new ArrayList<String[]>();
String nextValue = null;
while (sc.hasNextLine()) {
String line = sc.nextLine();
if("NODE_COORD_SECTION".equals(line)){
while (sc.hasNextLine()) {
nextValue = sc.nextLine();
storing.add(nextValue.trim().split(" "));
}
}
}
sc.close();
}
public static ArrayList<String[]> returnScanner() throws Exception {
Tree tree = new Tree();
return tree.storing;
}
public static void main(String[] args) throws Exception {
ArrayList<String[]> storedValues = returnScanner();
String[] firstLine = storedValues.get(0);
String[] secondLine = storedValues.get(1);
for (int i = 0; i < firstLine.length; i++) {
System.out.println(firstLine[i]);
}
}
}
My output:
1
565.0
575.0
Use the scanner to move to the next line until it encounters the phrase "NODE_COORD_SECTION". Then the subsequent lines are you data lines. They all conform to the format so you can use split to get the 2nd and third elements.
Stop reading and storing in your array when you reach a line which states "EOF".
How much do you care about the header of the TSP file? If you want to store this information and check that it is correct against the data in the file, rather than just running to the line "NODE_COORD_SECTION" you would want to look for the line: "DIMENSION" and store the value as an int. Then check this value against your final total in your ArrayList "storing"

Finding closest number from two arraylists

Recently one of my data servers went down and a large number of video files are damaged (over 15,000 files, or more than 60TB). I wrote a script to check all files and put results in a very big log.txt file (almost 8GB).
I wrote code to find all lines starting with "Input #0" and lines which contain "damaged", then added their line numbers to ArrayList's. Next, I need to compare those two ArrayLists and find the closest line number in list2 to the number in list1 so I can get back file names from the log file.
For example:
if list1 contains numbers {1, 5, 45, 55, 100, 2000... etc}
and list2 contains numbers {50, 51, 53, 2010... etc} the result should be {45, 2000... etc}
This is my current code:
import java.io.*;
import java.util.*;
public class Log {
public static void main(String [] args) throws IOException{
ArrayList<Integer> list1 = new ArrayList<Integer>();
ArrayList<Integer> list2 = new ArrayList<Integer>();
File file = new File("C:\\log.txt");
try {
Scanner scanner = new Scanner(file);
Scanner scanner2 = new Scanner(file);
int lineNum = 0;
int lineNum2 = 0;
while (scanner.hasNextLine()){
String line = scanner.nextLine();
String line2 = scanner.nextLine();
lineNum++;
lineNum2++;
if((line.startsWith("Input #0"))) {
list1.add(lineNum);
}
if((line2.contains("damaged"))) {
list2.add(lineNum2);
}
}
This is what I'm getting from the code above:
list1 [5, 262, 304, 488, 523, 1189, 1796, 2503, 2722, 4052, 4201, 4230, 4298, 4312, 4559, 4887, 4903, 5067....]
list2 [1838, 1841, 1842, 1844, 1851, 1861, 1865, 1866, 1868, 1875, 1878, 1879, 1880, 1881, 1886, 1887, 1891....]
Some log data:
Input #0, mpegvideo, from '/cinegy/cinegy/VIDEO/BSF/BLOK 3 - 14. NOVHighb668ca7d201411141051110636.m2v':
.
.
.
.
.
.
Data with damage:
Input #0, mpegvideo, from '/cinegy/cinegy/VIDEO/BSF/BLOK 3 - 14. NOVHighb668ca7d201411141051110636.m2v':
.
.
.
.
.
[error 0x090010] file damaged at 16 09
[error 0x090010] file damaged at 19 15
The log for each individual file does not contain any pattern except for the first 5-6 lines or so. Both damaged and non-damaged files contain info written in 20 to 100+ lines.
So, from these numbers the first result should be number 1796.
I'm pretty much a novice in Java and I need help.
Here's a small code that will do the work, but I don't know if you want redundant values in the result, so I saved them in a list and in a set, choose the one you prefer:
public static void main(String[] args) {
int[] list1 = {5, 262, 304, 488, 523, 1189, 1796, 2503, 2722, 4052, 4201, 4230, 4298, 4312, 4559};
int[] list2 = {1838, 1841, 1842, 1844, 1851, 1861, 1865, 1866, 1868, 1875, 1878, 1879, 1880, 1881};
ArrayList<Integer> resultList = new ArrayList<Integer>();
Set<Integer> resultSet = new HashSet<Integer>();
int j = 0;
for(int i = 0; i < list2.length; i++){
for(; j < list1.length; j++){
if(list1[j] > list2[i])
break;
}
resultList.add(list1[j-1]);
resultSet.add(list1[j-1]);
}
System.out.println(resultList);
System.out.println(resultSet);
}
Output:
[1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796]
[1796]
You defined two scanners (seems unnecessary) but you are only using one of them and calling nextline() twice on it. It looks like that is not intended and as a consequence the results you are getting are erroneous. It would be very helpful if you could post a sample excerpt from your logfile (you can filter the sensitive data) so that we can determine what the best approach is for this.
I think you should scrap your current approach because it does not seem like an efficient way to solve your problem of needing to find filenames of damaged files.
Depending on how your data looks, you can use regular expressions and possibly even extract the filenames directly into a Set.
Edit: Added some rough code that should do the job for you if you are indeed correct that each file starts with "Input #0". As long as there is a pattern in the log data for each file, then you should always be able to extract the data you need directly instead of going through the mess of matching entries from two separate arraylists.
public static void main(String [] args) throws FileNotFoundException{
Set<String> damagedFiles = new LinkedHashSet<String>();
File file = new File("C:\\log.txt");
Scanner scanner = new Scanner(file);
String filename = null;
try {
int lineNum = 0;
while (scanner.hasNextLine()){
String line = scanner.nextLine();
if(line.startsWith("Input #0")){
/*if desired, can use a regex lookahead to get only the path and filename
instead of the entire Input #0 line */
filename = line;
}
if(line.contains("damaged")){
if (filename != null){
damagedFiles.add(filename);
}
}
}
} finally {
scanner.close();
for (String s : damagedFiles){
System.out.println(s);
}
}
}
This is the result I got when running this code on a sample log file where I named the damaged files dmg#.m2v
Input #0, mpegvideo, from '/cinegy/cinegy/VIDEO/BSF/BLOK 3 - 14. dmg1.m2v':
Input #0, mpegvideo, from '/cinegy/cinegy/VIDEO/BSF/BLOK 3 - 14. dmg2.m2v':
Input #0, mpegvideo, from '/cinegy/cinegy/VIDEO/BSF/BLOK 3 - 14. dmg3.m2v':
Input #0, mpegvideo, from '/cinegy/cinegy/VIDEO/BSF/BLOK 3 - 14. dmg4.m2v':

Reading txt file, then re organizing it to an array

So basically what I need to do is:
Read a text file like this:
[Student ID], [Student Name], Asg 1, 10, Asg 2, 10, Midterm, 40, Final, 40
01234567, Timture Choi, 99.5, 97, 100.0, 99.0
02345678, Elaine Tam, 89.5, 88.5, 99.0, 100
and present it like this (with calculations of rank and average):
ID Name Asg 1 Asg 2 Midterm Final Overall Rank
01234567 Timture Choi 99.5 97.0 100.0 99.0 99.3 1
02345678
Elaine Tam 89.5 88.5 99.0 100.0 97.4 2
Average: 94.5 92.75 99.5 99.5 98.3
Using printf() function
now this is what I have done so far:
import java.io.*;
import java.util.Scanner;
class AssignmentGrades {
public static void main(String args[]) throws Exception {
Scanner filename = new Scanner(System.in);
String fn = filename.nextLine(); //scannig the file name
System.out.println("Enter your name of file : ");
FileReader fr = new FileReader(fn+".txt");
BufferedReader br = new BufferedReader (fr);
String list;
while((list = br.readLine()) !=null) {
System.out.println(list);
}
fr.close();
}
}
So I can ask the user for the name of the file, then read it and print.
Now.. I'm stuck. I think I need to probably put it in to array and split?
String firstrow = br.readLine();
String[] firstrow = firstrow.split(", ");
something like that?.. ugh ive been stuck here for more than an hour
I really need help!! I appreciate your attention!! ( I started to learn java this week)
There are two ways for splitting the input line just read from the file
Using String object's split() method which would return an array. Read more about the split here.
StringTokenizer Class - This class can be used to divide the input string into separate tokens based on a set of delimeter. Here is a good tutorial to get started.
You should be able to get more examples using google :)
In case you want to parse integers from String. Check this.
Here I store the columns as an array of Strings and I store the record set as an ArrayList of String arrays. In the while loop if the column set is not initialized yet (first iteration) I initialize it with the split. Otherwise I add the split to the ArrayList. Import java.util.ArrayList.
String[] columns = null;
ArrayList<String[]> values = new ArrayList<String[]>();
String list;
while((list = br.readLine()) !=null) {
if (columns != null) {
columns = list.split(", ");
} else {
values.add(list.split(", "));
}
}
fr.close();

CSV Reader empty values java

I have this CSV:
0,102000082,,2,125,'Battery location','Left-hand drive',2,2
0,300000029,102000082,3,895,'Behind the cab','Left',2,-7
0,102000082,,4,127,'Battery location','Right-hand drive',4,4
^-----
I use csvReader to map to a bean
public static List<BatteryBean> loadAndRead{
File csvFilename = new File("C:\\my.csv");
CSVReader csvReader = new CSVReader(new FileReader(csvFilename));
ColumnPositionMappingStrategy strat = new ColumnPositionMappingStrategy();
strat.setType(BatteryBean.class);
String[] columns = new String[] { "ktypnr","sentenceId","parentId","sortOrder", "adjItemNoteId","sentText","itemNoteText","parentSortOrder1","parentSortOrder10" };
strat.setColumnMapping(columns);
CsvToBean csv = new CsvToBean();
List<BatteryBean> list = csv.parse(strat, csvReader);
return list;
}
public static void main(String[] args) {
try {
List<BatteryBean> list = loadAndRead("C:\\work\\battery_report_raw.csv");
for (Object object : list) {
BatteryBean bb = (BatteryBean) object;
System.out.println(bb.getKtypnr());
}
}
So the problem is that the file contains empty strings between ,, and I get an exeption at parsing :
Caused by: java.lang.NumberFormatException: For input string: ""
I resolved. I have another question
Csv file
ktypnr sentence_id parent_id sort_order adj_item_note_id sent_text iem_note_text
0 102000082 2 125 Battery location' Left-hand drive'
0 300000029 102000082 3 895 Behind the cab' Left'
0 102000082 4 127 Battery location' Right-hand drive'
0 300000029 102000082 5 898 Behind the cab' Right'
So if one sentence_id = one parent_id i should combine those two so that looks like this(example first line and second line) but I should consider also the sort_order:
0, Battery location, Left-hand drive, Behind the cab, Left
I don't know how to proceed
Change parentId to String data type in BatteryBean. It seems it is integer.

Categories