I'm working on a project where I have a text file with the first line being the size of the array I'll need and then subsequent lines have course information in the following order: dept, num, title. (ex. CSC 101 Basic Computing) My code complies but when it runs the first index in the array becomes the default(i.e. nothing) and therefore the last line in the text file doesn't get stored or printed. I'm wondering how I can fix this error.
import java.util.Scanner;
import java.io.*;
public class Organizer {
public static void main(String[] args) {
Scanner fileScanner = null;
String file;
File f = null;
//Create a Do While loop in order to prompt the user for a input file
//and then continue prompting if the file entered does not exist.
do {
try {
System.out.print("What is the name of the input file? ");
Scanner inputReader = new Scanner(System.in);
file = inputReader.nextLine();
f = new File(file);
fileScanner = new Scanner(new File(file));
//Catch the exception and tell the user to try again
} catch (FileNotFoundException e) {
System.out.println("Error scanning that file, please try again.");
}
} while (!f.exists());
//Testing the Make Array Method
//System.out.print(makeArray(fileScanner));
//Testing the print Array Method
printArray(makeArray(fileScanner));
}
public static Course[] makeArray(Scanner s) {
int arraySize = s.nextInt();
String title = "";
String dept = "";
int num = 0;
Course[] a = new Course[arraySize];
for (int i = 0; i < a.length; i++) {
a[i] = new Course(dept, num, title);
String oneLine = s.nextLine();
Scanner lineReader = new Scanner(oneLine);
while (lineReader.hasNext()) {
dept = lineReader.next();
a[i].setDept(dept);
num = lineReader.nextInt();
a[i].setNum(num);
while (lineReader.hasNext()) {
title = title + lineReader.next() + " ";
}
a[i].setTitle(title);
}
title = " ";
}
return a;
}
public static void printArray(Course[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i].toString());
}
}
}
Here is my other class.
public static class Course {
//INSTANCE VARIABLES
private String dept = "";
private int num = 0;
private String title = "";
//CONSTRUCTORS
public Course(String dept, int num) {
this.dept = dept;
this.num = num;
}
public Course(String dept, int num, String title) {
this.dept = dept;
this.num = num;
this.title = title;
}
public Course() {
this.dept = "AAA";
this.num = 100;
this.title = "A course";
}
//SETTER AND GETTER METHODS
public void setDept(String dept) {
this.dept = dept;
}
public void setNum(int num) {
this.num = num;
}
public void setTitle(String title) {
this.title = title;
}
public String getDept() {
return this.dept;
}
public int getNum() {
return this.num;
}
public String getTitle() {
return this.title;
}
//TOSTRING METHOD
public String toString() {
return dept + " " + num + ": " + title;
}
}
Don't forget where your cursor in your Scanner is at each moment.
s.nextLine() will read the whole line and then the cursor will jump to the next line, while s.nextInt() will read one int from your line and then stay there. It won't check if this has been the last input for that line.
Just fix your code to:
int arraySize = s.nextInt();
s.nextLine();
and your code should run just fine!
(also consider changing a[i].setTitle(title); to a[i].setTitle(title.trim());, since you will always be left with a white space at the end of your title..)
nextInt method does not consume the new line character. Here is a solution that works:
public static Course[] makeArray(Scanner s){
int arraySize = s.nextInt();
String title = "";
String dept = "";
int num = 0;
Course[] a = new Course[arraySize];
s.nextLine();
for (int i = 0; i < a.length; i++){
a[i] = new Course(dept, num, title);
String oneLine = s.nextLine();
Scanner lineReader = new Scanner(oneLine);
while (lineReader.hasNext()){
dept = lineReader.next();
a[i].setDept(dept);
num = lineReader.nextInt();
a[i].setNum(num);
while (lineReader.hasNext()){
title = title + lineReader.next() + " ";
}
a[i].setTitle(title);
}
title = " ";
}
return a;
}
Related
I've created a class Scoreboard that will store entries of the name of a player, their power, their score, and their rank amongst other players. I want to use Collections.binarySearch() to retrieve the correct object of the name the user enters. However, it only gives back negative indexes. Any help is appreciated.
My comparator object:
import java.util.Comparator;
public class SortByName implements Comparator<Scoreboard> {
#Override
public int compare(Scoreboard s1, Scoreboard s2) {
return s1.getName().compareTo(s2.getName());
}
}
My main class:
import java.io.File;
import java.io.IOException;
import java.util.*;
public class Main {
public static void main (String args[]) throws IOException {
String get = "";
Scanner in = new Scanner(System.in);
Scanner inFile = new Scanner(new File("input.txt"));
// Temporarily saves the attributes of each Scoreboard object being created
int score;
int entryCount = 0;
String name = "";
String power;
ArrayList<Scoreboard> scoreboard = new ArrayList<>();
String line;
while (inFile.hasNextLine()) {
line = inFile.nextLine();
if (line == "") {
continue;
}
ArrayList<String> lineArray = new ArrayList<>();
for (int i = 0; i < line.split(" ").length; i++) {
lineArray.add(line.split(" ")[i]);
}
if (lineArray.size() < 3) {
continue;
}
try {
score = Integer.parseInt(lineArray.get(0));
lineArray.remove(0);
} catch (NumberFormatException e) {
continue;
}
entryCount++;
power = lineArray.get(lineArray.size() - 1);
lineArray.remove(lineArray.size() - 1);
for (int i = 0; i < lineArray.size(); i++) {
name += lineArray.get(i) + " ";
}
scoreboard.add(new Scoreboard(name, power, score, entryCount, entryCount));
name = "";
}
String input;
do {
System.out.print("Search name: ");
input = in.nextLine();
if ((input.equalsIgnoreCase("exit"))) break;
System.out.println("");
Collections.sort(scoreboard);
for (Scoreboard element:scoreboard) {
System.out.print(element);
}
System.out.println(input);
System.out.println(Collections.binarySearch(scoreboard, new Scoreboard(input, null, 0, 0, scoreboard.get(0).getRankOutOf()), new SortByName()));
} while (true);
}
}
I am trying to write program to sort Student data, which is in String form.
Student data (String) is input by user separated by space.
There is the input data format "Name,Age,marks1,marks2".
Sort the data in descending order based on total marks.
If String str="Rahul,22,67,87 Uma,23,89,90 Vinay,21,78,90";
then output should be Uma,23,89,90 Vinay,21,78,90 Rahul,22,67,87
I have writing this program, but landed up in NumberFormatException. Can someone please help me understand where am I making the mistake?
public static void main(String[] args) `enter code here`
{
Scanner scan=new Scanner(System.in);
//System.out.println("ENter String with separaed by space : ");
//String str=scan.nextLine();
String str="abc,12,98,56 def,23,77,88";
String [] data=str.split(" ");
for(int i=0; i<data.length; i++)
{
System.out.println("After split "+data[i]);
}
SortingStudent ss=new SortingStudent();
ss.getArranged(data);
}
void getArranged(String[] metadata)
{
for(int i=0; i<metadata.length; i++)
{
Integer sum=0;
System.out.println("After passing to method "+metadata[i]);
String s=metadata[i];
String data[]=s.split(",");
for(int j=0; j<data.length; j++)
{
System.out.println("After split 1 string "+data[j]);
sum = sum + (Integer.parseInt(data[j]));
System.out.println("sum= "+sum);
j = j + 3;
}
sum=0;
}
}
Following code should achieve what you are trying to do.
The idea is; split your input by <spaces> to extract each student record. Pass that as student metadata to your getArranged() method. Inside this method, use a TreeMap to store the student data sorted on descending order of total marks as the key and the metadata as the value. Rest of the code is self-explanatory
Approach-1:
import java.util.Collections;
import java.util.Map;
import java.util.TreeMap;
public class SortingStudent {
public static void main(String[] args) {
//input string. You may Scanner and take user input from command line
String str = "Rahul,22,67,87 Uma,23,89,90 Vinay,21,78,90";
System.out.println("Input is : " + str);
//extracting each student record - which are separated by <space>
String[] data = str.split(" ");
SortingStudent ss = new SortingStudent();
System.out.println("Output is : " + ss.getArranged(data));
}
String getArranged(String[] metadata) {
//Map to store student data sorted, based on total marks
Map<Integer, String> studentData = new TreeMap<Integer, String>(Collections.reverseOrder());
//Use Collections.reverseOrder() to sort the total marks in descending order
//iterate through each student record
for (int i = 0; i < metadata.length; i++) {
Integer sum = 0;
String s = metadata[i];
//Extract student marks
String data[] = s.split(",");
//find the total marks
for (int j = 2; j < data.length; j++) {
sum = sum + (Integer.parseInt(data[j]));
}
studentData.put(sum, s);
}
//construct the result
StringBuffer result = new StringBuffer();
for (Map.Entry<Integer, String> map : studentData.entrySet()) {
result.append(map.getValue() + " ");
}
return result.toString().trim();
}
}
However, if you really want to achieve this, leveraging Java's Object Oriented features and Collections framework; following code is one of the ways to do
Approach-2:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
public class SortingStudent {
public static void main(String[] args) {
//input string. You may Scanner and take user input from command line
String str = "Rahul,22,67,87 Uma,23,89,90 Vinay,21,78,90";
System.out.println("Input is : " + str);
//extracting each student record - which are separated by <space>
String[] data = str.split(" ");
SortingStudent ss = new SortingStudent();
System.out.print("Output is :");
for(Student s : ss.getArranged(data)) {
System.out.print(" " + s);
}
}
private Set<Student> getArranged(String[] metadata) {
//Set to store student data sorted, based on total marks
Set<Student> studentData = new TreeSet<Student>(Collections.reverseOrder());
//Use Collections.reverseOrder() to sort the total marks in descending order
//iterate through each student record
for (int i = 0; i < metadata.length; i++) {
String s = metadata[i];
String data[] = s.split(",");
Student student = new Student();
student.setName(data[0]);
student.setAge(Integer.parseInt(data[1]));
for (int j = 2; j < data.length; j++) {
student.addMarks(Integer.parseInt(data[j]));
}
studentData.add(student);
}
// System.out.println(studentData);
return studentData;
}
}
class Student implements Comparable<Student> {
private String name;
private int age;
private List<Integer> marks;
public Student() {
marks = new ArrayList<Integer>();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public List<Integer> getMarks() {
return marks;
}
public void setMarks(List<Integer> marks) {
this.marks = marks;
}
public void addMarks(int marks) {
this.marks.add(marks);
}
public int getTotalMarks() {
int totalMarks = 0;
for(int marks : marks)
totalMarks += marks;
return totalMarks;
}
#Override
public int compareTo(Student otherStudent) {
return Integer.compare(this.getTotalMarks(), otherStudent.getTotalMarks());
}
#Override
public String toString() {
StringBuffer content = new StringBuffer();
content.append(name);
content.append(",");
content.append(age);
content.append(",");
int i = 0;
for(; i < marks.size()-1; i++)
content.append(marks.get(i)+",");
content.append(marks.get(i));
return content.toString();
}
}
Could you please explain why this loop doesn't work in case if user types "yes" and why there are errors with variables initialisations.
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
public static void main(String args[]) {
Scanner src;
String amount;
String counterparty;
String dt;
String ct;
System.out.println("Create new transaction:yes/no");
Scanner abc = new Scanner(System.in);
String g = abc.nextLine();
if (g=="yes") {
System.out.println("Amount of transaction:");
src = new Scanner(System.in);
amount = src.nextLine();
System.out.println("Counterparty:");
counterparty = src.nextLine();
System.out.println("Dt:");
dt = src.nextLine();
System.out.println("Ct:");
ct = src.nextLine();
}
else if (g=="no") {
amount="0";
}
System.out.println("Transaction:");
ArrayList <String> Provodka = new ArrayList();
Provodka.add(amount);
Provodka.add(counterparty);
Provodka.add(dt);
Provodka.add(ct);
for (int i = 0; i < Provodka.size(); i++) {
String value = Provodka.get(i);
System.out.println("Element: " + value);
}
}
}
Just initialize the local variables and use equals() method instead of "=="
public static void main(String args[]) {
Scanner src;
String amount = null;
String counterparty = null;
String dt = null;
String ct = null;
System.out.println("Create new transaction:yes/no");
Scanner abc = new Scanner(System.in);
String g = abc.nextLine();
if (g.equals("yes"))
{
System.out.println("Amount of transaction:");
src = new Scanner(System.in);
amount = src.nextLine();
System.out.println("Counterparty:");
counterparty = src.nextLine();
System.out.println("Dt:");
dt = src.nextLine();
System.out.println("Ct:");
ct = src.nextLine();
}
else if (g.equals("no")){
amount="0";
}
System.out.println("Transaction:");
ArrayList <String> Provodka = new ArrayList();
Provodka.add(amount);
Provodka.add(counterparty);
Provodka.add(dt);
Provodka.add(ct);
for (int i = 0; i < Provodka.size(); i++) {
String value = Provodka.get(i);
System.out.println("Element: " + value);
}
}
In your string comparison you are comparing strings with '==' .
Use equals() method to compare strings.
eg:-
if ("yes".equals(g)){
}
Firstly, there is a lot of unnecessary declaration of Scanner. Using one variable for scanner will work for all inputs. Secondly, declare your variables above the main method and make them static, here you will not always need to initialise them. Finally, use g.equalsIgnoreCase("yes") instead of g == "yes", this way if you type yes in CAPS or not it will still register. Try what was done below
public static String g;
public static String amount;
public static String counterparty;
public static String dt;
public static String ct;
public static void main(String args[]) {
Scanner s = new Scanner(System.in);
System.out.println("Create new transaction:yes/no");
g= s.nextLine();
if (g.equalsIgnoreCase("yes")) {
System.out.println("Amount of transaction: ");
amount = s.nextLine();
System.out.println("Counterparty: ");
counterparty = s.nextLine();
System.out.println("Dt: ");
dt = s.nextLine();
System.out.println("Ct: ");
ct = s.nextLine();
}
else if (g.equalsIgnoreCase("no")) {
amount = "0";
}
System.out.println("Transaction:");
ArrayList <String> Provodka = new ArrayList();
Provodka.add(amount);
Provodka.add(counterparty);
Provodka.add(dt);
Provodka.add(ct);
for (int i = 0; i < Provodka.size(); i++) {
String value = Provodka.get(i);
System.out.println("Element: " + value);
}
}
}
It compiles just fine... but throws a "java.lang.NullPointerException" error on when I try to enter the index (as an integer). I thought I already gave index an int type so I'm not sure why this happens.
I'm new to java so if you guys have any pointers on something else I need to look into or try those tips, would be appreciated as well.
import java.util.Scanner;
class LineEditor
{
public static void main (String [ ] args)
{
//variables
String myLine;
String str;
int index;
Scanner scan = new Scanner(System.in);
//creates original myLine
myLine = new String ("Computer Science");
System.out.println ("The original string of text is: " + myLine);
//variable inputs
System.out.println("Enter a string to alter myLine: ");
str = scan.next();
System.out.println("Enter an index for the string to be inserted at: ");
index = scan.nextInt();
Insert insert = new Insert(str, index);
System.out.println ("The altered string is: " + insert.strIntoMyLine());
}
}
class Insert
{
String str;
int index;
String myLine;
public Insert (String s, int i)
{
str = s;
index = i;
}
String strIntoMyLine()
{
String part1;
String part2;
part1 = myLine.substring (0, index);
part2 = myLine.substring (index);
return (part1 + str + part2);
}
}
It seems that there is nothing present in myLine.
Replace Insert insert = new Insert(str, index); with Insert insert = new Insert(str, index,myLine);.
and public Insert (String s, int i) with public Insert (String s, int I, String myLine)
Also
this.myLine = myLine; in the constructor
your constructor should be
public Insert(String s, int i, String r) {
str = s;
num = i;
myLine = r;
}
and pass value like this "Insert insert = new Insert(str, index,myLine);"
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 8 years ago.
Below is the error:
Exception in thread "main" java.lang.NullPointerException
at CellularData.addCountry(CellularData.java:34)
at CellularData.addCountry(CellularData.java:24)
at TestCSVReader.main(TestCSVReader.java:35)
I keep getting the error above but seem to have trouble fixing it. I am reading from a csv file and displaying the data on the screen. Basically it reads country, the year, and it stats of a cellular data in double. Below is CellularData class:
public class CellularData {
private Object [][]array;
private int year;
public CellularData(int rows, int columns, int year)
{
array = new Object[rows+1][columns+1]; //add +1 because initializes the header.
this.year = year;
for(int i=1;i<=columns;i++)
{
array[0][i] = year++; //increments the year
}
}
public void addCountry(String country, double []num)
{
for(int i=0;i<array.length;i++)
{
if(array[i][0] == null) //checks if the first row is empty
{
//CellularData.addCountry(CellularData.java:24)
addCountry(country, num, i); //inserts the data
break;
}
}
}
private void addCountry(String country, double []num, int row)
{
array[row][0] = country;
for(int j = 1;j<array[row].length;j++)
{
array[row][j] = num[j-1]; //CellularData.addCountry(CellularData.java:34)
}
}
public double getNumSubscriptionsInCountryForPeriod(String country, int sYear, int eYear)
{
double sum = 0;
for (int i = 1; i < array.length; i++) {
if (country.equalsIgnoreCase((String) array[i][0])) { //matches with the parameters passed ignoring CAPS
int start = 1 + sYear - year; //first index position of the year
int end = start + (eYear - sYear); //end position of the year
if (start >= 0 && end < array[i].length) { //checks to see if index position is out of bounds
for (int k = start; k <= end; k++) {
// System.out.println(">> " + country + " adding " + array[i][k]);
sum += (Double) array[i][k]; //sum of the stats
}
}
else {
//returns Error messgae and -1
System.out.println("ERROR : requested year "+sYear+" from "+ country+" is less than starting year "+this.year);
sum = -1;
}
}
}
return sum;
}
public String toString()
{ //prints the array.
for(Object []a: array)
{
for(Object k:a)
{
System.out.print(k + "\t");
}
System.out.println();
}
return " ";
}
}
Here is my csv reader file and this where i read from the file:
public class CSVReader {
String[] countryNames;
int[] yearLabels;
double[][] cellularDatatables;
Scanner scan;
public CSVReader(String filename)// throws FileNotFoundException
{
try{
File file = new File(filename);
scan = new Scanner(file);
scan.nextLine();
String numLine = scan.nextLine();
final int n = Integer.parseInt(numLine.split(",")[1]); //Number is the string portion after the first comma
//Allocate arrays with length n
countryNames = new String[n];
cellularDatatables = new double[n][];
//Read in the header line of years, parse and copy into yearNum
String[] yearHeaders = scan.nextLine().split(",");
final int m = yearHeaders.length-1;
yearLabels = new int[m];
for(int i=0;i<m;i++)
{
yearLabels[i] = Integer.parseInt(yearHeaders[i+1]); //i+1 to skip the first entry in the string arr
}
//Now read until we run out of lines - put the first in country names and the rest in the table
int c = 0;
while(scan.hasNext())
{
String[] inputArr = scan.nextLine().split(",");
countryNames[c] = inputArr[0];
cellularDatatables[c] = new double[m];
for(int i = 0; i < m; i++)
{
cellularDatatables[c][i] = Double.parseDouble(inputArr[i+1]);
}
}
scan.close();
}
catch(FileNotFoundException e)
{
System.out.println(e.getMessage());
}
}
public String[] getCountryNames(){
return countryNames;
}
public int[] getYearLabels(){
return yearLabels;
}
public double[][] getParsedTable(){
return cellularDatatables;
}
public int getNumberOfYears()
{
return yearLabels.length;
}
}
And also TestCSVReader file:
public static void main(String[] args)
{
final String FILENAME = "data/cellular.csv";
CSVReader parser = new CSVReader(FILENAME);
String [] countryNames = parser.getCountryNames();
//System.out.println(countryNames.length);
int [] yearLabels = parser.getYearLabels();
//System.out.print(yearLabels.length);
double [][] parsedTable = parser.getParsedTable();
CellularData datatable;
int numRows = parsedTable.length;
int numColumns =parser.getNumberOfYears();
int startingYear = yearLabels[0];
datatable = new CellularData(numRows, numColumns, startingYear);
for (int countryIndex = 0; countryIndex < countryNames.length; countryIndex++)
{
double [] countryData = parsedTable[countryIndex];
datatable.addCountry(countryNames[countryIndex], countryData);//Error TestCSVReader.java:35
}
System.out.printf(countryNames[0] + " (1960 to 2012): %.2f \n", datatable.getNumSubscriptionsInCountryForPeriod(countryNames[0],1960,2012));
// the output is: Aruba (1960 to 2012): 1170.50
array[row][0] = country;
for(int j = 1;j<array[row].length;j++)
{
array[row][j] = num[j-1]; //CellularData.addCountry(CellularData.java:34)
}
Since the first line doesn't give NullPointerException, we know that array is not null and array[row] is not null. Therefore, num must be null.