I have two java classes. Schedule is the main class that uses an array of Jobs called deadline. I'm having problems putting anything in array. I have a for loop that reads data from a text file (it works fine) and inserts certain data into deadline. I not successfully creating deadline because whenever I want to start inserting into the array I get a NullPointerException. (The code below the ... obviously isn't what I actually coded, but it is still the same situation.)
It has been a while since I've coded in Java, so I might be just overlooking something simple, but I'm not really sure what it could be... Thanks for any help you can give.
public class Schedule {
private Job []deadline;
Schedule (int n){
Job[] deadline = new Job[n];
}
...
int n = 7;
Schedule schedule = new Schedule(n);
deadline[0] = new Job("A",3,40); // This line won't compile. NullPointerException
}
public class Job {
private String name;
private int deadline;
private int profit;
Job(String n, int d, int p){
name = n;
deadline = d;
profit = p;
}
}
You are shadowing deadline in your constructor, so you don't initialize the class member deadline, but the local one. Change it to:
private Job []deadline;
Schedule (int n){
deadline = new Job[n];
// ^^ note - no Job[] here
}
Related
I know how to count most things when it comes to Java, but this has either stumped me a lot, or my brain is dying. Anyway, I have a class called "Jobs", and within that class is a String variable called "day". Multiple new Jobs have been created already (exact number is unknown), and now I need to query and find out how many Jobs are on x day. I assume it would be easy enough with a while loop, but I don't know how to create one that looks through Jobs as a whole rather than one specific one.
The Job data was created by reading a file (the name of which is jobFile) via a Scanner.
public class Job_16997761 {
private int jobID; // unique job identification number
private int customerID; // unique customer identification number
private String registration; // registration number for vehicle for this job
private String date; // when the job is carried out by mechanic
private String day; // day of the week that job is booked for
private double totalFee; // total price for the Job
private int[] serviceCode; // the service codes to be carried out on the vehicle for the job
//Constructor
public Job_16997761(int jobID, int customerID, String registration,
String date, String day, double totalFee, int[] serviceCode) {
this.jobID = jobID;
this.customerID = customerID;
this.registration = registration;
this.date = date;
this.day = day;
this.totalFee = totalFee;
this.serviceCode = serviceCode;
}
Not sure why you are creating a dynamic instance of a job (eg. Job_16997761, it seems that each job has its own class). But when creating the jobs you can maintain a map that will have the number of jobs per day. Something like:
Map<String, Long> jobsPerDay=new HashMap<String,Long>();
Then when creating a new job you can simply increment the counter for each day:
jobsPerDay.put(day,jobsPerDay.get(day)!=null?jobsPerDay.get(day)++:1);
This way you will be able to get the number of jobs for a day by using: jobsPerDay.get(day)
Please note that you can use java.time.DayOfWeek instead of a String.
It's hard to tell you correct solution unless you give more details. You are saying you can write while loop so I will assume you have a collection of Job already.
int count = 0;
List<Job> jobs = readJobsFromFile();
for(Job job : jobs) {
if(job.getDay().equals(inputDay)){ //inputDay is day you have to find number of jobs on.
count++;
}
}
System.out.Println(count);
This is just one of the many ways and may not be that efficient, but this is one way you may consider (Before you edited your last post). Using an arrayList to contain all the Job objects and iterate through the objects.
import java.util.*;
public class SomeClass {
public static void main(String[] args)
{
Jobs job1 = new Jobs(1);
Jobs job2 = new Jobs(1);
Jobs job3 = new Jobs(2);
Jobs job4 = new Jobs(2);
Jobs job5 = new Jobs(2);
ArrayList<Jobs> jobList = new ArrayList<Jobs>();
jobList.add(job1);
jobList.add(job2);
jobList.add(job3);
jobList.add(job4);
jobList.add(job5);
System.out.println(numOfJobOnDayX(jobList, 2)); //Jobs which falls on day 2
}
public static int numOfJobOnDayX(ArrayList<Jobs> jobList, int specifiedDay)
{
int count=0;
for(int x=0; x<jobList.size(); x++) //May use a for-each loop instead
if(jobList.get(x).days == specifiedDay)
count ++;
return count;
}
}
OUTPUT: 3
Class for Jobs..
class Jobs
{
int days;
public Jobs(int days)
{
this.days = days;
}
}
For simplicity, I am not using any getter and setter methods. You may want to think about what data structure you want to use to hold your objects. Once again, I need to re-emphasize this may not be an efficient way, but it gives you some ideas some possibilities of doing the count.
This is a fairly simple question, but I am a beginner and I've been stuck on this part for hours now. I am not looking for an easy way out, but instead I just want to understand what is happening to my code and why it isn't working. My problem was:
Create a node class with a random number and the current time.
Create a storage class and store those nodes in a list/array.
Use the main class to create 50 nodes and display.
When I run it 50 times and get my list, I made the list print out the time so that I could check to see if my code was running, and they all have the same time. It means that different nodes aren't being stored into my list, and are instead being wiped out each time the loop runs. Why is that?
My code is attached:
Main:
public class NodeSort {
public static void main(String[] args)
{
int c = 0;
while (c < 50)
{
Storage.add();
c++;
}
}
}
Node:
public class Node
{
public static int num;
public static long time;
public Node()
{
num = Random.getNum();
time = System.nanoTime();
}
public static long getTime()
{
return time;
}
public static int getNum()
{
return num;
}
}
Storage:
public class Storage
{
public static ArrayList<Node> list = new ArrayList<>();
public static void add()
{
list.add(new Node());
}
When I do get time for x = 1-50, it prints out the same time 50 times instead of 50 different ones.
They all have the same time value because they're all getting created at almost the same time. System.nanoTime() doesn't guarantee that you'll actually get nanosecond precision, it's up to the operating system's ability to discern time. Most OSes can only provide millisecond resolution. So if all of the calls happen within the same millisecond, you'll get the same values.
As far as the random number is concerned, I don't know--what is the Random class? It's not java.util.Random.
Edit: Oh wait, I see it. You declared num and time as static in your Node class. That means there's only one copy of each in existence. Just remove static from those declarations, and from the methods that return the values.
This is a class I've written and it feels 'clunky', like there should be a better way to set this up without needing the extra method setList() to instantiate the array. I'm trying to only leave in the parts relevant to my question, as well as an example of what I did the first time that threw a runtime (not compiletime) error. I'm still mostly used to interpreted languages, so the stricter rules of Java are taking some getting used to.
public class Numbersplode
{
// fields
private int before;
private int goal;
private int[] processed;
// constructors
Numbersplode(int begin, int finish)
{
this.before = begin;
this.goal = finish;
this.processed = this.setList(begin);
this.transList();
}
// mutators
private int[] setList(int begin)
{
int[] result = new int[begin];
return result;
}
public void transList()
{
// transforms the list
int count;
double temp;
for (count = 0; count < this.before; count++)
{
temp = (double)count/(double)this.before * (double)this.goal;
this.processed[count] = (int)temp;
}
}
}
It seems like I should be able to avoid having the setList() method, but when I tried this (everything else the same):
public class Numbersplode
{
// fields
private int before;
private int goal;
private int[] processed = new int[before];
// constructors
Numbersplode(int begin, int finish)
{
this.before = begin;
this.goal = finish;
this.transList();
}
[..............]
I receive java.lang.ArrayIndexOutOfBoundsException: 0 since processed[] apparently can't be defined that way.
That extra class seems to solve the problem, but it seems to me that the Constructor should define those variables all at the same time of object creation, thus allowing for the array processed to be defined at the same time in that way.
So is there a more elegant solution I'm missing? If I find one before this is solved I'll post it up here.
EDIT
Just to be clear, if I compile the class (or even a program that creates an object from that class) I don't have any problems until I actually run the program (thus the runtime problem vs compiletime, but wanted to be clear)
And why even have a setList() method -- a private(?) mutator. Why not simply set processed = new int[before] in your constructor?
Numbersplode(int before, int goal) {
this.before = before;
this.goal = goal;
processed = new int[before];
transList();
}
Not quite sure why this won't work, when i try to compile and run it gives me a null pointer exception. I know it's super simple and probably a stupid question but I can't seem to figure it out!
import javax.swing.JOptionPane;
public class Whatever
{
private int age;
private String name;
private float salary;
public Whatever ()
{
String userName = JOptionPane.showInputDialog ("What is your name?");
Whatever listData[] = new Whatever [10];
listData[6].name = userName;
}
public static void main (String [] args)
{
Whatever testWhatever = new Whatever ();
}
}
Array of Whatever instances - all are null.
I would guess you'd have another problem with OutOfMemoryError as soon as you fix it, because when you call new to initialize the Whatever array elements they'll construct their own arrays and call new, and so on until you get OOM error.
I'll spell it out for you so you can get to the next error:
import javax.swing.JOptionPane;
public class Whatever
{
private int age;
private String name;
private float salary;
public Whatever () {
String userName = JOptionPane.showInputDialog ("What is your name?");
Whatever listData[] = new Whatever[10];
for (int i = 0; i < listData.length; ++i) {
listData[i] = new Whatever(); // This is where you'll get the OOM error. See why?
}
// You'll never get here.
listData[6].name = userName;
}
public static void main (String [] args)
{
Whatever testWhatever = new Whatever();
}
}
And you're putting Swing code in a constructor? Did you intend this as an example of how to write bad code?
Just for future reference, you should run your code in a good IDE - like IntelliJ, the best on the market - with debugging turned on and step through the code. You'll figure it out pretty quickly where the problem lies, faster than asking at SO will tell you.
So yes, it's a pretty stupid example. Hopefully you aren't writing anything like this for real.
With this
Whatever listData[] = new Whatever [10];
you initialized a new Array, but the elements in the Array are not initialized.
So you get a NullPointerException when you access listData[6].name.
You could try this:
for(int i = 0; i < listData.length; i++) {
listData[i] = new Whatever();
}
, but please do this not in the constructor itself.
Because then you would get OutOfMemoryException like duffymo said.
Try to do this directly in main for example.
The error i am having here is a infinite or near infinite loop in my method calls and class's creating other class's constructors. What my program is trying to do is semi-randomly generate survey results based off actual statistics. I would highly appreciate not only some insight in whats going wrong here. But some advice and pointers on how to prevent this from happening and ways to analyze the error messages by myself. I get how some of the work but like i stated below i am new to programming im a freshman in college so programming is new to me. Thanks in advance and sorry for my previous post, thought i would take the time to give you guys an appropriate one.
Im new to programming this is my 2nd project ive done on my own so im sorry if its not the best.
This is my Test class:
public Tester()
{
randomGenerator = new Random();
probability = new Probability();
stats = new Statistics();
double chance = randomGenerator.nextDouble();
double gender = probability.getProbabilityOfMale();
if(chance > gender)
{
male = false;
stats.incrementFemale();
}else{
male = true;
stats.incrementMale();
}
age = randomGenerator.nextInt(49)+16;
int range = stats.getNumberOfQuestion();
for(int i=0;i<range;i++)
{
probabilities = probability.probOfAnswer(i);
answers = probability.getAnswers(i);
chance = randomGenerator.nextDouble();
int size = probabilities.size();
for(int j=0;j<size;j++)
{
double qTemp = chance - probabilities.get(j);
if(qTemp <= 0.0)
{
Answer aTemp = answers.get(j);
aTemp.incrementCounter();
answers.set(j,aTemp);
}
}
}
}
Statistics class:
public ArrayList<Answer> getAnswers(int index)
{
temp = survey.getAnswers(index);
return temp;
}
public int getMale()
{
return male;
}
public int getFemale()
{
return female;
}
public int getNumberOfQuestion()
{
return numberOfQuestion;
}
public void incrementNumberOfQuestion()
{
numberOfQuestion++;
}
public void incrementMale()
{
male++;
}
public void incrementFemale()
{
female++;
}
and probability class:
public Probability()
{
stats = new Statistics();
probOfAnswer = new ArrayList<Double>(0);
}
public ArrayList<Double> probOfAnswer(int index)
{
temp = stats.getAnswers(index);
int size = temp.size();
for(int i=0;i<size;i++)
{
aTemp = temp.get(i);
for(int j=0;j<size;j++)
{
Answer aTemp = temp.get(j);
sum += (double)aTemp.getCounter();
}
double number = (double)aTemp.getCounter();
probOfAnswer.add(number/sum);
sum = 0;
}
return probOfAnswer;
}
public ArrayList<Answer> getAnswers(int index)
{
temp = stats.getAnswers(index);
return temp;
}
public ArrayList<Double> getProbofAnswer()
{
return probOfAnswer;
}
public void probabilityOfMale()
{
double male = (double)stats.getMale();
double female = (double)stats.getFemale();
probabilityOfMale = male / (male + female);
}
public double getProbabilityOfMale()
{
return probabilityOfMale;
}
These are the only real important parts where the loop exsists the rest of the code is not needed to be uploaded.
Im having difficulty uploading my error message on this site its not accepting it as code in the code insert, then it wont let me submit the message afterwards so im going to upload the code elseware and link it.
http://forum.overdosed.net/index.php/topic/56608-this-is-unimportant/
But i dont know how long that forum will let me keep that post there ><
at Question.<init>(Question.java:17)
at Survey.addQuestion(Survey.java:23)
at Statistics.<init>(Statistics.java:52)
at Question.<init>(Question.java:17)
at Survey.addQuestion(Survey.java:23)
at Statistics.<init>(Statistics.java:52)
at Probability.<init>(Probability.java:19)
You need to check why Question is creating Statistics object and again Statistics is trying to create Question object leading to infinite recursion. As the line numbers are given you can take a look at corresponding lines.
Judging by the stack trace, the problem lies in three parts which you haven't shown us - the Question and Statistics constructors and the Survey.addQuestion method:
From the stack trace:
at Survey.addQuestion(Survey.java:23)
at Statistics.<init>(Statistics.java:52)
at Question.<init>(Question.java:17)
at Survey.addQuestion(Survey.java:23)
at Statistics.<init>(Statistics.java:52)
at Question.<init>(Question.java:17)
So your Question constructor is calling the Statistics constructor. But the Statistics constructor is then calling Survey.addQuestion, which is in turn calling the Question constructor.
It feels to me like there's much more construction going on than is really useful. Why would a Statistics constructor need to add anything to a survey? I wouldn't expect a Statistics class to even know about surveys and questions.
It's entirely possible that a lot of this can be fixed by passing a reference to an existing object to the constructors - so the Probability constructor may be better taking a Statistics reference in its constructor and using that for its stats field than creating a new Statistics object itself. It's hard to say without knowing what these classes are really meant to represent though... which may be part of the problem. Do you have a firm grasp of what the responsibility of each class is? Think about that carefully before making any code changes.
We don't have the relevant source code, but the error message says what's wrong:
Tester creates a Probability
Probability constructor creates a Statistics
Statistics constructor calls Survey.addQuestion()
addQuestion() creates a Question
Question creates a Statistics (goto 3 and loop infinitely)
I think you should probably pass objects around rather than creating them each time.