I have built a method which compares objects attributes with user input int. The method then adds all the objects to an array(the assignment demands it to be an Array and not ArrayList). After its added I have a foor-loop which prints out a list of Results for an athlete(in user input), it prints out all results from one category and then another and so forth..
I keep getting a NullPointerException error on the last line which is a System.out.println. I have searched for an answer for hours, and read the NullPointerException posts here but cannot find the issue or solve it.
for (int x = 0; x < category.size(); x++) {
Category c = categories.get(x);
System.out.println("Result in " + c.categoryName() + " for " + matchedAthlete.surName() + " "
+ matchedAthlete.lastName() + ": ");
for (int i = 0; i < individarrayresult.length; i++) {
Result res = individarrayresult[i];
if (res.nameOfCategory().equals(c.categoryName())) {
System.out.println(res.categoryResult());
}
}
}
So the last line of code ( System.out.println ) gets the NullPointerException, I am desperete for help. Below is the Array filled with results from only 1 Athlete.
Result[] individarrayresult = new Result[resultlist.size()];
for (int i = 0; i < resultlist.size(); i++) {
Result res = resultlist.get(i);
if (res.athleteStartNumber() == DSN) {
individarrayresult[i] = res;
}
}
If you have a NullPointerException on that row:
System.out.println(res.categoryResult());
The problem is in the method categoryResult because res is not null, otherwyse the previous test
if (res.nameOfCategory().equals(c.categoryName())) {
must throw the NullPointerException prior of the System.out.
So check the code of categoryResult() or post it.
Perhaps, as T.J. said, that the problem is not on that row but on the previous row and the NullPointerException is related to the value of res. Post the complete StackTrace and row lines of your code to be sure of that answer.
I think you're mistaken, I think you're getting the NPE one line earlier, on this line:
if (res.nameOfCategory().equals(c.categoryName())) {
And the reason you're getting it is there are nulls in your array, because of how you fill it:
Result[] individarrayresult = new Result[resultlist.size()];
for (int i = 0; i < resultlist.size(); i++) {
Result res = resultlist.get(i);
if (res.athleteStartNumber() == DSN) {
individarrayresult[i] = res;
}
}
If res.athleteStartNumber() == DSN is false, you never assign anything to individarrayresult[i], so that array entry keeps its null default.
How to fix it:
Build up a list of matching results:
List<> individResults = new Arraylist<Result>(resultlist.size());
for (int i = 0; i < resultlist.size(); i++) {
Result res = resultlist.get(i);
if (res.athleteStartNumber() == DSN) {
individResults.add(res);
}
}
...and then either use that list directly, or convert it to an array:
Result[] individarrayresult = individResults.toArray(new Result[individResults.size()]);
...and use the resulting array.
(You can also do the same with the nifty new streams stuff in the latest version of Java, but I'm not au fait with them...)
It's possible, of course, that you're getting the NPE on the line you said you are and that there are two problems, and it just happens you've been processing all DSN entries so far. If so, and you fix the other problem, the first time you have a non-DSN entry, you'll run into this problem unless it fix it as well.
Related
I have a data string name stringSplit that I want to split into 5 parts.
I use this to split the String:
String[] pisah = stringSplit.split(",", -1);
for (int i=0;i< pisah.length;i++) {
String hasil1 = pisah[0];
String hasil2 = pisah[1];
String hasil3 = pisah[2];
String hasil4 = pisah[3];
String hasil5 = pisah[4];
}
When the value in stringSplit there are 5 data (f.e: “data1,data2,data3,data4,data5”), the code is working properly. But when in stringSplit there are only one, two or three data, an exception will caught:
(f.e: java.lang.ArrayIndexOutOfBoundsException: length=4; index=4).
And my question is how to handle the empty string? So even though the data only one, two, or three data the stringSplit still can be splitted.
I've tried by adding limit to -1 which this solution I got from another post, but still not working for me.
Editted:
I almost forgot, the result string (hasil1 - hasil5) will use for edittext.
fe: editText1.setText(hasil1);
and others.
One possible solution is to check if the index you are looking for is less than the length of the array. If that index is less than the size of the array than it definitely exists.
for (int i=0;i< pisah.length;i++) {
if(0 < pisah.length)
String hasil1 = pisah[0];
if(1 < pisah.length)
String hasil2 = pisah[1];
//similarly for all other idexes that you want the value for.
}
You have hard coded the number of EditText fields you can have! What if, there is a change in requirement, where you have to add another field? That would need you to add "editText6" and "hasil6" at a lot of places. The code is not nimble footed to changes in specs.
This is what I would do.
Create a list of EditText, say, textList
Iterate over the pisah array, and textist simultaneously and add the String at index i in pisah to the EditText object at index i in
textList.
This way, in case there are only 3 data values, you are automatically taking care of populating only 3 EditText objects.
This is the code :
List<EditText> textList;
String[] pisah = stringSplit.split(",", -1);
for (int i=0;i< pisah.length;i++) {
textList.get(i).setTest(pisah[i]);
}
use this code:
String res[] = new String[5];
String[] pisah = stringSplit.split(",");
for (int i=0;i< pisah.length && i < res.length;i++) {
res[i] = pisah[i];
}
if(res[0] != null )
//.......... res[0] valid
if(res[1] != null )
//.......... res[1] valid
if(res[2] != null )
//.......... res[2] valid
if(res[3] != null )
//.......... res[3] valid
if(res[4] != null )
//.......... res[4] valid
Here is the problem,
for (int i=0;i< pisah.length;i++) {
String hasil1 = pisah[0];
String hasil2 = pisah[1];
String hasil3 = pisah[2];
String hasil4 = pisah[4];
String hasil5 = pisah[5];
}
but that iterates over the list and gets the values in the list from 0-5 every time it loops, so what you should be doing is something like this
for(int i = 0; i < 6; i++){
if(i >= pisah.length()) break;
String hasilI = pisah[i];
}
This iterates over the list 6 times then if the list's size < 6 it will break out of the loop
This particular line in a method throws an NPE, and I'm stuck on it for two days:
List<Peak>[] peaks = (List<Peak>[]) new ArrayList[samples.length/Spectra.spectraInterval];
The method in which the line occurs is:
public static List<Peak>[] getPeaks(AudioClip clip) {
double[] samples = clip.getSamples();
List<Peak>[] peaks = (List<Peak>[]) new ArrayList[samples.length/Spectra.spectraInterval];
peaks[0] = new ArrayList<Peak>();
for (int i = 1; i < peaks.length; i++) {
Spectra s = new Spectra(i, Arrays.copyOfRange(
samples,
i*Spectra.spectraInterval - Spectra.samplesPerSpectra/2,
i*Spectra.spectraInterval + Spectra.samplesPerSpectra/2
));
peaks[i] = s.getPeaks();
//System.out.println(peaks[i]);
}return peaks;
}
This method is part of a class, Extractor that extracts the difference in time required for two peaks to get paired into a Probe. My question is:
Is the Peak object creation wrong? or the conversion to ArrayList wrong?
Is the NPE due to samples.length (declared in another class) returning null?
Pl help. I am new to Java, just working my way around a Shazam-like code that has an audio file input - trying to replace that with a mic input in a different class.
Try investigate that using some logs (maybe samples is null?):
System.out.println("samples = " + samples + ", interval = " + Spectra.spectraInterval);
List<Peak>[] peaks = (List<Peak>[]) new ArrayList[samples.length/Spectra.spectraInterval];
An NPE is raised, if something gets called on an object, whose value is null. (methods, attributes).
In your case there are two such calls in this line:
samples.length and Spectra.spectraInterval.
Spectra.spectraInterval seems to be a static call, which will not raise an NPE, even if the value of spectraInterval is null. (Because it's absolutely legit to return null values.)
The samples array on the other hand comes from the AudioClip. Check if there is a value present and handle it, if not.
E.g.,
public static List<Peak>[] getPeaks(AudioClip clip) {
double[] samples = clip.getSamples();
if(samples == null || samples.length == 0) {
return Collections.emptyList().toArray();
}
List<Peak>[] peaks = (List<Peak>[]) new ArrayList[samples.length/Spectra.spectraInterval];
peaks[0] = new ArrayList<Peak>();
for (int i = 1; i < peaks.length; i++) {
Spectra s = new Spectra(i, Arrays.copyOfRange(
samples,
i*Spectra.spectraInterval - Spectra.samplesPerSpectra/2,
i*Spectra.spectraInterval + Spectra.samplesPerSpectra/2
));
peaks[i] = s.getPeaks();
//System.out.println(peaks[i]);
}
return peaks;
}
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 5 years ago.
The program looks slightly advanced; it is not. Simple manipulation of array.
The program compiles correctly, however, it encounters an exception run-time.
Exception in thread "main" java.lang.NullPointerException
at Ordliste.leggTilOrd(Tekstanalyse.java:85)
at Tekstanalyse.main(Tekstanalyse.java:23)
So there is something wrong with if(s.equalsIgnoreCase(ordArray[k])).
I cannot see why. It even provides the correct output.
import java.io.File;
import java.util.Scanner;
import java.io.FileNotFoundException;
public class Tekstanalyse {
public static void main(String[] args) throws FileNotFoundException {
Ordliste ol = new Ordliste();
ol.lesBok("scarlet.text");
ol.leggTilOrd("A");
}
}
class Ordliste {
private int i = 0;
private String[] ordArray = new String[100000];
private int antForekomster;
private int arrStorrelse = 0;
public void lesBok(String filnavn) throws FileNotFoundException {
File minFil = new File(filnavn);
Scanner scan = new Scanner(minFil);
while (scan.hasNextLine()) {
ordArray[i] = scan.nextLine();
//System.out.println(ordArray[i]);
i++;
arrStorrelse++;
}
System.out.println("Array size: " + arrStorrelse + " Capacity: " + ordArray.length);
}
public void leggTilOrd(String s) {
for (int k = 0; k < ordArray.length; k++) {
if (s.equalsIgnoreCase(ordArray[k])) {
antForekomster++;
System.out.println("Den har vi sett for!");
} else {
s = ordArray[arrStorrelse];
}
}
}
}
I'm pretty sure the error is right here:
for (int k = 0; k < ordArray.length; k++) {
if (s.equalsIgnoreCase(ordArray[k])) {
antForekomster++;
System.out.println("Den har vi sett for!");
} else {
s = ordArray[arrStorrelse]; // <- dangerous
}
}
As I said in the comment, ordArray could contain null elements if the read text file does not contain 100.000 lines of text. If this is the case, the above line would write null to s because s.equalsIgnoreCase(null) is false.
You should think about using a list instead of an array.
private List<String> ordList = new ArrayList<String>();
(or use a different variable name, it is up to you)
Then you can add new entries to the list using ordList.add(scan.nextLine());. This list won't contain any null elements and your mentioned problem should be gone.
I would highly recommend you to simply use a debugger to debug your code , but here goes:
in your lesBok method you fill your array with strings and make a counter arrStorrelse. to be the amount of elements in the array you made. however the array is filled for indexes 0 to n-1. and arrStorrelse is equal to N you did however allocate space in the array for this. so when in leggTilOrd() you iterate the first time and you enter the else clause you do this
for (int k = 0; k < ordArray.length; k++) {
if (s.equalsIgnoreCase(ordArray[k])) {
antForekomster++;
System.out.println("Den har vi sett for!");
}
else {
int arrStorrelse2=arrStorrelse;
s = ordArray[arrStorrelse];
}
in that else clause s is set to ordArray[arrStorrElse]; however arrStorrElse is at that moment one higher than the last intialised element of your array. so it sets s to the null pointer.
then the next iteration of your loop in the if clause
if (s.equalsIgnoreCase(ordArray[k])) {
antForekomster++;
System.out.println("Den har vi sett for!");
the s.equalsIgnoreCase() call is done on an s that is null that's where the null pointer exception comes from.
you need to change the arrStorrElse assignment you haven't explained what it should do so i can't do that for you also try to learn how to debug your code here is a usefull link:
http://www.tutorialspoint.com/eclipse/eclipse_debugging_program.htm
I have compiled and tested your code.
s.equalsIgnoreCase(null)
throws nullPointerException.
Maybe you should try to use ArrayList instead of Array to avoid iterating through nulls.
It took me some time to figure out why the NullPointerException occurs and I have to agree with Piotr and Tom: The NPE is caused by the line
s.equalsIgnoreCase(ordArray[k])
and a side-effect in your code. This side-effect is introduced by reassigning the parameter s in the else-branch to null (this value comes from ordArray[arrStorrelse]). After this reassignment happened, you will have something like this:
null.equalsIgnoreCase(ordArray[k])
And voila, there is the NullPointerException.
so I made my own class-object for the date (DMY.java), and when I try to sort the list, the memory usage goes from 20,000k to almost 700,000k. I have narrowed it down to the sorting method that was causing the memory to go through the roof. It instantiates a few objects in the method, so I assume that is what is taking all of the memory up. But does anyone think that they can help me optimize it to use less memory? Here is the code:
public static ArrayList<String> sortListByDate(ArrayList<String> list)
{
DMY currDate = null;
DMY oldDate1 = null;
DMY oldDate2 = null;
ArrayList<String> temp = new ArrayList<String>();
for(int x = 0; x < list.size(); x++) {
currDate = new DMY(Regex.matchPattern(list.get(x), "\\d+[-]\\d+[-]\\d+ \\d+[:]\\d+[:]\\d+").trim(), false);
if(temp.size() == 0) {
temp.add(list.get(x));
} else if(temp.size() == 1) {
oldDate1 = new DMY(Regex.matchPattern(temp.get(0), "\\d+[-]\\d+[-]\\d+ \\d+[:]\\d+[:]\\d+").trim(), false);
if(currDate.compareToFull(oldDate1) == -1) {
temp.add(0, list.get(x));
} else {
temp.add(list.get(x));
}
} else {
for(int y = 0; y < temp.size(); y++) {
if(!(x + 1 < temp.size())) {
temp.add(list.get(x));
} else {
oldDate1 = new DMY(Regex.matchPattern(temp.get(x), "\\d+[-]\\d+[-]\\d+ \\d+[:]\\d+[:]\\d+").trim(), false);
oldDate2 = new DMY(Regex.matchPattern(temp.get(x + 1), "\\d+[-]\\d+[-]\\d+ \\d+[:]\\d+[:]\\d+").trim(), false);
if(currDate.compareToFull(oldDate1) == 1 && currDate.compareToFull(oldDate2) == -1) {
temp.add(x + 1, list.get(x));
}
}
}
}
}
return temp;
}
Basically, if the size of the sorted list is 0, just add the line to the new list. If the size of the sorted list is 1, see if the new date is before or after that one date, then add it to the sorted list accordingly. Otherwise, simply loop through each value in the list and see if the date of the next two lines are newer or older than the current one. Then add it accordingly.
As you can see, there are a lot of objects and a lot of loops. The original list is a list of strings that contain a date. What the method does is get the date using regex and then compares it to the other dates in the list. For some reason it is using a lot of memory and I need to reduce it. Any ideas?
Make use of Collections.sort instead of rolling your own
Use a Comparator to implement the desired sorting behavior
Refrain from using expensive operations that implicitly create Objects (e.g. RegEx, String.trim()). If you can't do without RegEx, at least precompile and reuse them.
Generally avoid object creation just for the sake of comparing
public static int intersectionSizeMergeAndSort(studentList L1, studentList L2) {
int intersectionSize = 0;
int[] C = new int[L1.studentID.length+L2.studentID.length];
for(int i = 0; i<L1.studentID.length; i++){
C[i] = L1.studentID[i];
}
for(int i = 0; i<L2.studentID.length; i++){
C[i+L1.studentID.length] = L2.studentID[i];
}
Arrays.sort(C);
int pointer = 0;
while(pointer<((L1.studentID.length)+(L2.studentId.length))){
if(C[pointer] = C[pointer+1]){
intersectionSize = intersectionSize + 1;
pointer = pointer + 2;
}
else {
pointer == pointer + 1;
}
return intersectionSize;
}
}
I have this algorithm I am writing for an assignment. Every time I compile my code, I get an error that I cannot understand in order to debug.
Error is as follows:
Error: /Users/nah/Desktop/studentList.java:137: operator < cannot be applied to int,<nulltype>
the error is pointing to the while loop statement
Not sure if this is directly related to the same error but your line
while(pointer<((L1.studentID.length)+(L2.studentId.length))){
has mis-spelt the second "studentId" and should be "studentID"
while(pointer<((L1.studentID.length)+(L2.studentID.length))){
that is of course unless you happen to have two arrays defined for your studentID class, each with a different case.
I also agree with the other answers related to the "==" comparison operator, but you're telling us the error is related to the while statement
The only error I can see is:
if(C[pointer] = C[pointer+1]){
this should be:
if(C[pointer] == C[pointer+1]){
The following will not work in Java:
if (C[pointer] = C[pointer+1])
This is assignment, its type is int, it cannot be used in the if statement
While loop ? Ok. Debugging is done by simplifying expressions.
The only thing where we see < is the loop condition. Instead of
int pointer = 0;
while(pointer<((L1.studentID.length)+(L2.studentId.length))){
do
int pointer = 0;
int len = ((L1.studentID.length)+(L2.studentId.length));
while(pointer< len){
If error again, simplify the error-raising expression.
I think that this question is mistitled. It is ** ambigous only because you do not attempt to localize it. Post a question only if "<" does not work for two integers. The current question title must be: "how do you debug Java programs?"