Parsing a CSV into 2D array generates NullPointerException - java

Using ReadInputCSVFromFile method to read the sample CSV from file and parse it to a String array after using split(",") function and pass it to a 2D array to read it fully.
PrintResultsForTesting method would be only for printing out the 2D array for visual overlook.
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Scanner;
public class CSVReader {
public static String[][] readIntoArray;
public static String[][] myArray;
public static String[][] csvResults;
public static int countRow = 0;
public static int countColumn = 0;
public static void main(String[] args) {
csvResults = ReadInputCSVFromFile(myArray);
PrintResultsForTesting(csvResults);
}
public static void PrintResultsForTesting(String[][] csvResults) {
String[][] newMyArray = new String[myArray.length][myArray[0].length];
for (int i = 0; i < csvResults.length; ++i) {
for (int j = 0; j < csvResults[0].length; ++j) {
System.out.println(csvResults[i][j]);
}
}
}
public static String[][] ReadInputCSVFromFile(String[][] myArray) {
countRow = 0;
countColumn = 0;
Scanner scanner;
String inputLine;
String fileLocation;
fileLocation = "D://WorkSpace_Git//methods//iq-distribution//docs/SAP.csv";
try {
scanner = new Scanner(new BufferedReader(new FileReader(fileLocation)));
while (scanner.hasNext()) {
inputLine = scanner.nextLine();
String[] readIntoArray = inputLine.split(",");
// count rows and columns
++countRow;
countColumn = readIntoArray.length;
myArray = new String[countRow][countColumn];
}
for (int i = 0; i < countRow; ++i) {
for (int j = 0; j < countColumn; ++j) {
myArray[i][j] = readIntoArray[i][j];
}
}
System.out.println("Rows: " + countRow + '\n' + "Columns: " + countColumn);
scanner.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return myArray;
}
}
The error is:
Exception in thread "main" java.lang.NullPointerException at project.CSVReader.ReadInputCSVFromFile(CSVReader.java:52) at project.CSVReader.main(CSVReader.java:16) Process finished with exit code 1

After looking briefly at your code, I could spot a bug. When this method is called:
public static String[][] ReadInputCSVFromFile(String[][] myArray) {
myArray is null.
If you want to write to the array, you will need to instantiate the array first.
If you are using arrays actually you should know in advance its dimensions. If you do not know it, consider using some implementation of java.util.List - like java.util.ArrayList.
Another problem is exception handling. If the file is not found, then the exception is caught and you still call this method PrintResultsForTesting with unpredicatable results. Better to use a throws clause and stop the execution alltogether. So instead of the try catch in method ReadInputCSVFromFile just use a throws FileNotFoundException in this method.

Related

Alphabetically sort contents of file using methods (Java)

The title might be a little misleading but I am writing a piece of code that has this as the contents of the text file:
04/26/16 Sega 3D Classics Collection
07/14/16 Batman: Arkham Underworld
06/24/16 Tokyo Mirage Sessions #FE
Essentially I want them to be in alphabetical order and it should make a brand new file that looks like this:
Batman: Arkham Underworld
Sega 3D Classics Collection
Tokyo Mirage Sessions #FE
What I have tried is to use the indexOf() method to extract only the names of the list of games from my existing text file. I have also tried to store them in a new array to avoid confusion for the computer. The problem is that when I try to store the indexOf of the info array into a new array, the line gives an error of "cannot convert from int to string" and I am not sure on how to fix the error.
This is my code below:
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;
public class Main{
public static void main (String[]args) throws IOException{
File file = new File("releasedates.txt");
String []arr = input(file);
output(file,arr);
outputSort1(file, arr);
}
public static String[]input (File file) throws FileNotFoundException{
String[]arr = new String[3];
Scanner sc = new Scanner(file);
for(int i = 0; i < arr.length; i++){
arr[i] = sc.nextLine();
}
return arr;
}
public static void output(File file, String[] info) throws IOException{
FileWriter writer = new FileWriter("fileName.txt");
for(String aString:info){
writer.write(aString);
}
writer.close();
}
public static void sortByMonth(String[]info){
String temp;
for (int j = 0; j < info.length; j++) {
for (int i = j + 1; i < info.length; i++) {
if (info[i].compareTo(info[j]) < 0) {
temp = info[j];
info[j] = info[i];
info[i] = temp;
}
}
}
}
public static void outputSort1(File file,String[] info) throws IOException{
sortByMonth(info);
FileWriter writer = new FileWriter("fileNameSorted1.txt");
for(String aString:info){
writer.write(aString);
}
writer.close();
}
public static void sortByName(String[]info){
String[] names = new String[3];
for(int i = 0; i < info.length; i ++){
names[i] = info[i].indexOf(" " ,info.length);
}
String temp;
for (int j = 0; j < names.length; j++) {
for (int i = j + 1; i < names.length; i++) {
if (names[i].compareTo(names[j]) < 0) {
temp = names[j];
names[j] = names[i];
names[i] = temp;
}
}
}
}
}
You've declared names array as String[] so you can't assign integer to it. indexOf method returns integer.
public static void sortByName(String[]info) {
String[] names = new String[3]; //<-- declaration suggests store string
for (int i = 0; i < info.length; i++) {
names[i] = info[i].indexOf(" ", info.length);//<-you are assigning integer
}
I think what you are trying to do is like this:
names[i] = info[i].substring(info[i].indexOf(" "), info[i].length());
Use java.nio APIs for file implementations as java.io apis are outdated. Also, if you use Stream operations then the implementation becomes much easier:
public class Test {
public static void main(String[] args) throws Exception {
Path file = Path.of("e:\\releasedates.txt");
List<String> records = Files.readAllLines(file);
List<String> sortedByName = records.stream()
.map(s -> s.substring(s.indexOf(" "), s.length()))
.sorted(String::compareTo)
.collect(Collectors.toList());
System.out.println(sortedByName);
Files.write(Path.of("e:\\fileNameSorted.txt"), sortedByName);
List<String> sortedByDate = records.stream().sorted(Test::compareDates)
.map(s -> s.substring(s.indexOf(" "), s.length()))
.collect(Collectors.toList());
System.out.println(sortedByDate);
Files.write(Path.of("e:\\fileDateSorted.txt"), sortedByDate);
}
public static int compareDates(String d1, String d2) {
d1 = d1.substring(0, d1.indexOf(" "));
d2 = d2.substring(0, d2.indexOf(" "));
LocalDate ld1 = LocalDate.parse(d1,
DateTimeFormatter.ofPattern("MM/dd/yy"));
LocalDate ld2 = LocalDate.parse(d2,
DateTimeFormatter.ofPattern("MM/dd/yy"));
return ld1.compareTo(ld2);
}
}
Answer by #onkar ruikar is correct. indexOf returns int and you are trying to store it in String. I would like to extend his answer, where you can store the game/movie names in TreeSet instead of Array, so that by default it will be sorted in alphabetical order.
If you want to allow duplicate game/movie names, then you can use ArrayList and call Collections.sort(<array list>) method, which will sort the ArrayList in alphabetical order.
Here is the detailed answer of how can we sort Collections in Java: https://stackoverflow.com/a/8725470/3709922

Counting the amount of times each letter shows in a file

Essentially, this code takes a file (which is a few paragraphs of text) and counts the amount of times each letter appears and prints it onto the console. While I've finished all the code in terms of calculation, I'm running into an exception. When I run this, it shows:
java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:862)
at java.util.Scanner.next(Scanner.java:1371)
at LetterCount.countOccurrences(LetterCount.java:29)
at LetterCount.main(LetterCount.java:20)
Here is my code:
// Document your class here
import java.util.Scanner;
import java.io.File;
import java.io.FileInputStream;
public class LetterCount {
public final static String FILENAME = "testFile.txt";
// Driver to test LetterInventory class
public static void main(String[] args) {
Scanner inputFile = null;
try {
inputFile = new Scanner(new File(FILENAME));
} catch (Exception e) {
System.out.println("File could not be opened: " + FILENAME);
System.exit(0);
}
int[] counts = countOccurrences(inputFile);
displayTable(counts);
resetTable(counts);
}
public static int[] countOccurrences (Scanner inputFile) {
int[]counts = new int[26];
char[] characters = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
while (inputFile.hasNextLine()) {
String theWord = inputFile.next();
theWord = theWord.toLowerCase();
for (int j = 0; j < theWord.length(); j++) {
for (int counter = 0; counter < 26; counter++) {
if (theWord.charAt(j) == characters[counter]) {
counts[counter] += 1;
}
}
}
}
return counts;
}
public static void displayTable (int[] counts) {
for (int index = 0; index < 26; index++) {
System.out.println((char)('a' + index) + ":\t" + counts[index]);
}
}
public static void resetTable (int[] counts) {
System.out.println();
for (int index = 0; index < 26; index++) {
System.out.println((char)('a' + index) + ":\t0");
}
}
}
When I clicked on the highlighted parts of NoSuchElementException, I saw that it was referring to the String I created. What am I doing wrong, and what can I do to fix it?
The method you use to read the data should be of the same type as the one you use to check if there is more data.
In your while statement, you use inputFile.hasNextLine(), so on the line after it, you should use inputFile.nextLine() (rather than inputFile.next() as you do now).
Alternatively, you can change the while statement to use inputFile.hasNext().
No guarantees, but try using inputFile.hasNext() in your while instead of inputFile.hasNextLine(). A next line being available is not necessarily the same thing as a next word being available.
You don't need the characters array (you can use the same math you have in display to perform the addition of counts). Also, you should be consistent with how you call Scanner.hasNextLine() and Scanner.next() (check for next with hasNext()). Something like,
public static int[] countOccurrences(Scanner inputFile) {
int[] counts = new int[26];
while (inputFile.hasNext()) {
String theWord = inputFile.next().toLowerCase();
for (char ch : theWord.toCharArray()) {
if (Character.isLetter(ch)) {
counts[ch - 'a']++;
}
}
}
return counts;
}

How to print two ArrayLists to a csv file with multiple columns?

I have two array lists like shown below,
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.*;
class Reader {
public static void main(String args[]) throws FileNotFoundException {
ArrayList<String> animal = new ArrayList<>();
animal.add("Dog");
animal.add("Cat");
animal.add("Mouse");
ArrayList<Integer> numbers = new ArrayList<>();
for (int i = 1; i <= 15; i++) {
numbers.add(i);
}
PrintWriter writer = new PrintWriter("animals.csv");
for (String ani : animal) {
writer.println(ani + ",");
}
writer.close();
}
}
I want the output to be like this in the .csv file.
Dog,1,2,3,4,5,
Cat,6,7,8,9,10,
Mouse,11,12,13,14,15,
When I use for-loops, the output of the array lists gets printed one below the other in the .csv file.
How do I format the array lists the way I desired, so it looks like this in Excel?
use writer.print() instead of writer.println()
Notice 'ln' in the method name you are using, which means print line.
Update: To also add numbers along with animal:
public static void main(final String[] args) throws FileNotFoundException {
ArrayList<String> animal = new ArrayList<>();
animal.add("Dog");
animal.add("Cat");
animal.add("Mouse");
ArrayList<Integer> numbers = new ArrayList<>();
for (int i = 1; i <= 15; i++) {
numbers.add(i);
}
PrintWriter writer = new PrintWriter("animals.csv");
List<String> row = new ArrayList<>();
int i = 0;
for (String ani : animal) {
row.add(ani);
for (int j = 0; j < 5; j++) {
row.add(String.valueOf(numbers.get(i++)));
}
writer.println(String.join(",", row));
row.clear();
}
writer.close();
}
Your writer method is printing a line. You need to use just print.
So writer.println(ani + ","); becomes writer.print(ani + ",");
Also, to add numbers as you asked you can do this as an alternative. This works as you said you have only 5 elements in each row after animal name.
PrintWriter writer = new PrintWriter("animals.csv");
int rowCounter = 0;
for (String ani : animals) {
writer.print(ani);
for (int i = rowCounter * 5; i < (rowCounter * 5 + 5); i++) {
writer.print("," + numbers.get(i));
}
writer.println();
rowCounter++;
}
writer.close();

Reading lines from 2 dimensional arrays

I'm trying to read from 2 dimensional arrays.
What this code does is that it first stores .txt file contents into 2d arrays, one line per element. It then compares user input to each array, looking for similarities. Any similarity will be stored in another array.
The thing here is that the comparing part doesn't work. Any hints as to why?
Thanks.
import java.awt.Point;
import java.io.File;
import java.util.Arrays;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Main {
static int RowCheck =0;
static int C_Row = 0;
static int S_Row = 0;
static String lexicon[][] = new String[3000][10];
static String results[][] = new String[100][10];
private static String find2DIndex(Object[][] array, Object search) {
if (search == null || array == null) return null;
for (int rowIndex = 0; rowIndex < array.length; rowIndex++ ) {
Object[] row = array[rowIndex];
if (row != null) {
for (int columnIndex = 0; columnIndex < 2; columnIndex++) {
if (search.equals(row[columnIndex])) {
for(int i=0; i<2; i++)
for(int j=0; j<=10; j++)
lexicon[i][j]=results[i][j];
return Arrays.deepToString(results);
}
}
}
}
return null; // value not found in array
}
public static void main(String[] args) throws FileNotFoundException {
File testlex = new File("C:\\Users\\Harry\\Documents\\testlex.txt");
File testlex2 = new File("C:\\Users\\Harry\\Documents\\textlex2.txt");
Scanner cc = new Scanner(testlex2);
Scanner sc = new Scanner(testlex);
while (sc.hasNextLine()){
int column = 0;
String line = sc.nextLine();
sc.useDelimiter("/ *");
if (line.isEmpty())
continue;
C_Row = C_Row + 1;
column = 0;
String[] tokens = line.split("\\s");
for (String token : tokens) {
if (token.isEmpty())
continue;
lexicon[C_Row][column] = token;
column++;
}
}
while (cc.hasNextLine()){
int column = 0;
String line = cc.nextLine();
cc.useDelimiter("/ *");
if (line.isEmpty())
continue;
S_Row = S_Row + 1;
column = 0;
String[] tokens = line.split("\\s");
for (String token : tokens) {
if (token.isEmpty())
continue;
lexicon[S_Row][column] = token;
column++;
}
}
sc.close();
cc.close();
find2DIndex(lexicon, "abash");
System.out.println(C_Row);
}
}
This line will compare search and row[columnIndex] as objects of type Object.
if (search.equals(row[columnIndex]))
Therefore it will compare references. You seem to want to compare contents of String objects. There are 2 ways you can modify find2DIndex for this.
Change the signature to
private static String find2DIndex(String[][] array, String search)
and replace any occurrence of Object in the function with String
Turn it into a generic method
private static <T> String find2DIndex(T[][] array, T search)
and replace any occurrence of Object in the function with T
In both cases equals will now be the method of String.

reading 2d array from txt file java scanner

I keep getting:
java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:909)
at java.util.Scanner.next(Scanner.java:1530)
at java.util.Scanner.nextInt(Scanner.java:2160)
at java.util.Scanner.nextInt(Scanner.java:2119)
at Driver0.readFile(Driver0.java:38)
at Driver0.main(Driver0.java:18)
Trying to use the scanner class since it's all I know so far. any help appreciated. Trying to read the 2d array but it never reads it fully. My input.txt file is:
3 5
2 3 4 5 10
4 5 2 3 7
-3 -1 0 1 5
import java.io.*;
import java.util.*;
public class Driver0 {
//public static String fileName; // declare so it may be used outside of main
public static int[][] array; // declare as empty until given dimensions
public static int dimensionA, dimensionB; // dimensions used in methods
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("What is the name of the data file?");
System.out.print("> ");
String fileName = input.nextLine();
readFile(fileName);
String nextCommand = "";
while (!(nextCommand.equals("quit"))) {
System.out.println("\nNext command");
System.out.print("> ");
nextCommand = input.nextLine();
choice (nextCommand);
}
}
public static void choice(String command) {
switch (command) {
case "help": System.out.println("show array\nrows sorted\ncols sorted"+
"increase row i by n\nincrease col j by n\nquit\n");
break;
default: showArray();
}
}
public static void readFile(String fileName) {
try {
Scanner foo = new Scanner(fileName);
dimensionA = foo.nextInt();
dimensionB = foo.nextInt();
array = new int[dimensionA][dimensionB];
while (foo.hasNext()) {
for (int row = 0; row < dimensionA; row++) {
foo.nextLine();
for (int column = 0; column < dimensionB; column++) {
array[row][column] = foo.nextInt();
}
}
}
foo.close();
}
catch(Exception e) {
e.printStackTrace(); // displays type of error
}
}
public static void showArray() {
for (int ro = 0; ro < dimensionA; ro++) {
for (int col = 0; col < dimensionB; col++) {
System.out.print(array[ro][col]);
}
System.out.println();
}
}
}
Go through methods in the Scanner class.
Specially, the hasXXX() and nextXXX() methods, they come in pairs. Try not to mix-match those methods which will make things complicated. You are using nextInt(), hasNext(), and nextLine(). The docs also explains what these methods do when you invoke them.
For your case, the methods hasNextLine() and nextLine() will be enough if you are willing to use the String.split(). You can split the string returned by nextLine() and parse the integer and assign it to the array element.
I think it's better to use ArrayList. try this
package readfile;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class Read {
public static void main(String[] args) throws FileNotFoundException, IOException {
String line = null;
List<String[]> list = new ArrayList<String[]>();
BufferedReader reader = new BufferedReader(new FileReader("/home/user/My_Folder/read_me.txt"));
while ((line = reader.readLine())!=null) {
list.add(getArray(line));
}
reader.close();
for (String[] stringArr : list) {
for(String str : stringArr){
System.out.print(str+" ");
}
System.out.println("");
}
}
private static String[] getArray(String s){
String[] array = s.split("\\s");
return array;
}
}

Categories