Please help me explaning this. I can't seem to figure out why this produce a null pointer exception
/* Try to find customer in customer list, if not in list add to list with a
new plan; otherwise add additional plan to customer*/
for(int a = 0; a < dataset.length; a++){
if(customer_name_list.contains(dataset[a][CLIENT_NAME])){
int temp_index = 0;
//NULLPOINTEREXCEPTION OCCURRED ON THE FOLLOWING LINE
while(!customer.get(temp_index).name.equals(dataset[a][CLIENT_NAME])){
temp_index++;
}
customer.get(temp_index).add_plan(dataset[a][PLAN], dataset[a][DETAIL]);
}
else{
Customer temp_customer = new Customer(dataset[a][CLIENT_NAME], dataset[a][PLAN], dataset[a][DETAIL]);
customer.add(temp_customer);
customer_name_list.add(dataset[a][CLIENT_NAME]);
}
}
Thank you for your help
Taking this as the line the exception occurs on:
while(!customer.get(temp_index).name.equals(dataset[a][CLIENT_NAME])){
There's a number of things that could be calling the issue. First off, customer could be null. Second, the results of customer.get(temp_index) could be null. Finally, customer.get(temp_index).name could also be null.
Since we're not working with the full code set here, I suggest you step through and print out the values to each of the above things to work out what one's null (or use a debugger.) That way you'll be able to see exactly what's causing the exception. My guess is that a customer's name may well be set to null which would cause the issue, but it could just as easily be any of the other things I mentioned.
If it isn't found you don't exit the loop, instead you keep going. Try adding a counter or clause so you don't go over.
Either your customer collection, or one of its elements, or the name field of one of its elements is null. I can't really say anything more without seeing what goes in the customer collection.
But a good idea is to print out temp_index in the loop in some kind of log file so you can see how many iterations does it complete before falling over.
Another thing you might find useful is to try to avoid multiple dereferencing operators (.) on the same line, especially if you know little about the data that is being accessed.
You could create a helper method for example:
private String getCustomerName( int index ) {
Customer c = customer.get( index );
return c.name;
}
And use it in your while loop.
Although unrelated, but as others have pointed out, your loop will end in an IndexOutOfBoundsException if no matching elements are found, so you'll have to fix that too.
for (dataA : dataset) {
if (customer_name_list.contains(dataA[CLIENT_NAME])) {
for (c : customer) if (dataA[CLIENT_NAME].equals(c.name)) {
c.add_plan(dataA[PLAN], dataA[DETAIL]);
break;
}
} else {
customer.add(new Customer(dataA[CLIENT_NAME], dataA[PLAN], dataA[DETAIL]));
customer_name_list.add(dataA[CLIENT_NAME]);
}
}
That's what you're doing, only cleaner. I suggest you might want to switch to either a hashing data structure (e.g., a HashMap) or a sorted data structure to improve your lookup and search calls. Then the above would look like
for (data : dataset) {
if ((Customer c = customer_map.get(data[CLIENT_NAME]))!=null) {
c.add_plan(data[PLAN], data[DETAIL]);
} else {
customer_map.put(data[CLIENT_NAME], new Customer(data[CLIENT_NAME], data[PLAN], data[DETAIL]));
}
}
which, in addition to be easier on the brain, is nicer performance-wise. If you need other stuff, like insert-order based iteration, you can use the appropriate map flavor.
As to the NPE, that means an item you've fetched isn't properly initialized - either the item at temp_index is null (and getting name throws the NPE), or name is null and trying to call equals on it throws the NPE. If the index weren't there, you'd be getting an out-of-bounds style exception.
Related
down bellow you can see two example methods, which are structured in the same way, but have to work with completely different integers.
You can guess if the code gets longer, it is pretty anoying to have a second long method which is doing the same.
Do you have any idea, how i can combine those two methods without using "if" or "switch" statements at every spot?
Thanks for your help
public List<> firstTestMethod(){
if(blabla != null){
if(blabla.getChildren().size() > 1){
return blabla.getChildren().subList(2, blabla.getChildren().size());
}
}
return null;
}
And:
public List<> secondTestMethod(){
if(blabla != null){
if(blabla.getChildren().size() > 4){
return blabla.getChildren().subList(0, 2);
}
}
return null;
}
Attempting to isolate common ground from 2 or more places into its own Helper method is not a good idea if you're just looking at what the code does without any context.
The right approach is first to define what you're actually isolating. It's not so much about the how (the fact that these methods look vaguely similar suggests that the how is the same, yes), but the why. What do these methods attempt to accomplish?
Usually, the why is also mostly the same. Rarely, the why is completely different, and the fact that the methods look similar is a pure coincidence.
Here's a key takeaway: If the why is completely different but the methods look somewhat similar, you do not want to turn them into a single method. DRY is a rule of thumb, not a commandment!
Thus, your question isn't directly answerable, because the 2 snippets are so abstractly named (blabla isn't all that informative), it's not possible to determine with the little context the question provides what the why might be.
Thus, answer the why question first, and usually the strategy on making a single method that can cater to both snippets here becomes trivial.
Here is an example answer: If list is 'valid', return the first, or last, X elements inside it. Validity is defined as follows: The list is not null, and contains at least Z entries. Otherwise, return null.
That's still pretty vague, and dangerously close to a 'how', but it sounds like it might describe what you have here.
An even better answer would be: blabla represents a family; determine the subset of children who are eligible for inheriting the property.
The reason you want this is twofold:
It makes it much easier to describe a method. A method that seems to do a few completely unrelated things and is incapable of describing the rhyme or reason of any of it cannot be understood without reading the whole thing through, which takes a long time and is error-prone. A large part of why you want methods in the first place is to let the programmer (the human) abstract ideas away. Instead of remembering what these 45 lines do, all you need to remember is 'fetch the eligible kids'.
Code changes over time. Bugs are found and need fixing. External influences change around you (APIs change, libraries change, standards change). Feature requests are a thing. Without the why part it is likely that one of the callers of this method grows needs that this method cannot provide, and then the 'easiest' (but not best!) solution is to just add the functionality to this method. The method will eventually grow into a 20 page monstrosity doing completely unrelated things, and having 50 parameters. To guard against this growth, define what the purpose of this method is in a way that is unlikely to spiral into 'read this book to understand what all this method is supposed to do'.
Thus, your question is not really answerable, as the 2 snippets do not make it obvious what the common thread might be, here.
Why do these methods abuse null? You seem to think null means empty list. It does not. Empty list means empty list. Shouldn't this be returning e.g. List.of instead of null? Once you fix that up, this method appears to simply be: "Give me a sublist consisting of everything except the first two elements. If the list is smaller than that or null, return an empty list", which is starting to move away from the 'how' and slowly towards a 'what' and 'why'. There are only 2 parameters to this generalized concept: The list, and the # of items from the start that need to be omitted.
The second snippet, on the other hand, makes no sense. Why return the first 3 elements, but only if the list has 5 or more items in it? What's the link between 3 and 5? If the answer is: "Nothing, it's a parameter", then this conundrum has far more parameters than the first snippet, and we see that whilst the code looks perhaps similar, once you start describing the why/what instead of the how, these two jobs aren't similar at all, and trying to shoehorn these 2 unrelated jobs into a single method is just going to lead to bad code now, and worse code later on as changes occur.
Let's say instead that this last snippet is trying to return all elements except the X elements at the end, returning an empty list if there are fewer than X. This matches much better with the first snippet (which does the same thing, except replace 'at the end' with 'at the start'). Then you could write:
// document somewhere that `blabla.getChildren()` is guaranteed to be sorted by age.
/** Returns the {#code numEldest} children. */
public List<Child> getEldest(int numEldest) {
if (numEldest < 0) throw new IllegalArgumentException();
return getChildren(numEldest, true);
}
/** Returns all children except the {#code numEldest} ones. */
public List<Child> getAllButEldest(int numEldest) {
if (numEldest < 0) throw new IllegalArgumentException();
return getChildren(numEldest, false);
}
private List<Child> getChildren(int numEldest, boolean include) {
if (blabla == null) return List.of();
List<Child> children = blabla.getChildren();
if (numEldest >= children.size()) return include ? children : List.of();
int startIdx = include ? 0 : numEldest;
int endIdx = include ? numEldest : children.size();
return children.subList(startIdx, endIdx);
}
Note a few stylistic tricks here:
boolean parameters are bad, because why would you know 'true' matches up with 'I want the eldest' and 'false' matches up with 'I want the youngest'? Names are good. This snippet has 2 methods that make very clear what they do, by using names.
That 'when extracting common ground, define the why, not the how' is a hierarchical idea - apply it all the way down, and as you get further away from the thousand-mile view, the what and how become more and more technical. That's okay. The more down to the details you get, the more private things should be.
By having defined what this all actually means, note that the behaviour is subtly different: If you ask for the 5 eldest children and there are only 4 children, this returns those 4 children instead of null. That shows off some of the power of defining the 'why': Now it's a consistent idea. Returning all 4 when you ask for 'give me the 5 eldest', is no doubt 90%+ of all those who get near this code would assume happens.
Preconditions, such as what comprises sane inputs, should always be checked. Here, we check if the numEldest param is negative and just crash out, as that makes no sense. Checks should be as early as they can reasonably be made: That way the stack traces are more useful.
You can pass objects that encapsulate the desired behavior differences at various points in your method. Often you can use a predefined interface for behavior encapsulation (Runnable, Callable, Predicate, etc.) or you may need to define your own.
public List<> testMethod(Predicate<BlaBlaType> test,
Function<BlaBlaType, List<>> extractor)
{
if(blabla != null){
if(test.test(blabla)){
return extractor.apply(blabla);
}
}
return null;
}
You could then call it with a couple of lambdas:
testMethod(
blabla -> blabla.getChildren().size() > 1,
blabla -> blabla.getChildren().subList(2, blabla.getChildren().size())
);
testMethod(
blabla -> blabla.getChildren().size() > 4,
blabla -> blabla.getChildren().subList(0, 2)
);
Here is one approach. Pass a named boolean to indicate which version you want. This also allows the list of children to be retrieved independent of the return. For lack of more meaningful names I choose START and END to indicate which parts of the list to return.
static boolean START = true;
static boolean END = false;
public List<Children> TestMethod(boolean type) {
if (blabla != null) {
List<Children> list = blabla.getChildren();
int size = list.size();
return START ?
(size > 1 ? list.subList(0, 2) : null) :
(size > 4 ? list.subList(2, size) :
null);
}
return null;
}
I'm trying to delete the middle node from a linked list given access to that node. I'm wondering if there is a difference between the two methods below, or do they accomplish the same thing?
public boolean deleteMiddle(Node middle){
Node next = middle.next; //line 2
middle.data = next.data;
middle.next = next.next;
return true;
}
public boolean deleteMiddle(Node middle){
middle.data = middle.next.data;
middle.next = middle.next.next;
return true;
}
The first method is what the textbook recommended but it seems like creating the Node "next" in the first method(line 2) is an unnecessary line of code.
I think you're probably right that they are equivalent (or certainly look that way)
In both cases it looks like there is a null pointer exception (on next.next) if the item you're deleting is the last in the list (e.g. if next is null then next.next is an error).
And if you get passed null of course that's also going to be a NPE.
creating the Node "next" in the first method(line 2) is an unnecessary line of code.
Both snippets achieve the same result.
But what the extra variable assignment (it does not "create a Node", it just assigns a new name to an existing one) does is avoiding to call middle.next twice, avoiding doing the same "calculation" twice.
In this example that won't make any real difference, but in general, it can be a usual performance optimization to avoid redundant work (especially if method calls are involved that do some "heavy lifting"). Before engaging in these adventures, though, one should think about if it is worth making the code potentially less legible, especially given that the JVM will try to do all kinds of optimization automatically. So apply this mindset only to simple patterns or real bottlenecks.
On top of that, giving names to intermediate results can also lead to more self-explanatory code (also not much difference here).
Final remarks: Sometimes (but not here) it is necessary to introduce extra variables to store things temporarily that would otherwise be overwritten in the course of the operation, such as the famous int h = x; x = y; y = h; example.
Yes, they're equivalent. I prefer the first one because it avoids the repetition of the expression middle.next.
As #Rick pointed out, when middle is the last element, you'll get an NPE in both cases.
Suppose I have 10 lines of code. Any line maybe throw a NullPointerException. I don't want to care about these exceptions. If a line throws the exceptions, I want the executor jump to next line and go forward. Could I do this on Java? if yes, please give me some sample code.
UPDATE: (add sample source for more clear question)
first.setText(prize.first);
second.setText(prize.second);
third.setText(prize.third);
fourth.setText(prize.fourth);
fifth.setText(prize.fifth);
sixth.setText(prize.sixth);
seventh.setText(prize.seventh);
eighth.setText(prize.eighth);
Suppose I have 8 lines of code above. What I want is: if the line 4 (or 5, 6,...) throws an exception, all other lines of code works normally. Of course I can use try...catch to catch the exceptions line by line. But this way make my source very complex.
This is impossible. If you think about it for a while, you'll realize that that is also a nonsense. Take this code for example:
String s = getSomeString(); // assigns null
int length = s.length; // throws NPE
if (length > 10) { // what would you do here?? length is un-initialized
domeSomething();
}
Edit
Now that you've updated you question with a code snippet, there are two general approaches to deal with nulls:
1. Disallow them where they aren't supposed to be
In your code snippet, you've provided a list of EditTexts, where any o them might be null. Well, in my opinion if you have an Activity in Android which should have some Views, then it is a programming error if any of them is null for whatever reason. An activity without some of its views can't work properly, so throwing a NPE and exiting the application is a perfectly sensible thing to do.
The NPE tells you "hey, you've made a mistake and you have to fix it". Until then, it is not safe for the app in an unpredicted state to continue execution, because no one knows what can happen, what data can become corrupted.
2. Allow them where they make sense, and provide null-checks
There are some places where you can have variables whose value can be empty. There are several approaches how to express an empty value and null is the most obvious one.
In that case, you can't just ignore the possibilty of a NPE and you have to do some null-checks. But again, a NPE is not your enemy. It will tell you that you've forgotten to account for all the possible situations that you should have.
Of course, repeated null checks make the code cluttered and noisy, so you can create some methods that generalize the null checks for you. I could not come up with a sensible example, so take this method only for illustration:
public void clearEditTexts(EditText... editTexts) {
for (EditText e : editTexts) {
if (e != null) {
e.setText("");
}
}
}
This method clears the contents of all the passed EditTexts. Any of them can be null, but this method does these null-checks internally, so you don't have to do it manually for each of them.
This question is also a very good reading about handling nulls:
Avoiding != null statements
This is not possible. If your variables can be null you will just have to check for that, or prevent them from being null. Very rarely it can be useful to create a dummy object implementation whose overridden methods do nothing, so it can be used in place of a valid object instead of null.
The fact that a variable is null is notable, and should not be ignored. Therefore, you'd want something like this:
...
if(first != null && prize.first != null)
{
first.setText(prize.first);
}
...
If, for some reason, you absolutely need to throw NPEs, you would need to surround each line with its own try/catch; there's no way to automatically catch exceptions and have it advance to the next line. It's not, however, recommended to do this.
...
try
{
first.setText(prize.first);
}
catch(NullPointerException e)
{
}
try
{
second.setText(prize.second);
}
catch(NullPointerException e)
{
}
...
No, you cant and you should care, they try to tell you whats wrong.
NullPointerException is a runtime (unchecked) exception and Java not reccomand to catch unchecked exceptions. You should have a solution to prevent it.
I am new to Java and especially to iterating through lists and modifying it's elements. I went through dozens of similar questions, but after many tries nothing worked.
In the following code sample an exceptions is thrown. It is not related to concurrent thread as I only have one thread. Netbeans output sais that the exception occurs in line 5(CustomerData customer = i.next();) :
CustomerData tempCustomer = new CustomerData("",tagID,0);
tempCustomer.setName(name);
tempCustomer.setSize(size);
for(ListIterator<CustomerData> i = customers.listIterator(); i.hasNext(); )
{
CustomerData customer = i.next();
if(customer.getTagID().contains(tagID))
{
Object[] options = {"overwrite", "do not overwrite"};
int n = JOptionPane.showOptionDialog(rootPane,
"TagID already exists. overwrite?",
"?",
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE,
null,
options,
rootPane);
if ( n == JOptionPane.YES_OPTION ){
i.set(tempCustomer);
}
}
else{
addCustomer();
}
}
The whole code is only supposed to check if the element has matching tagID and if it does, replace two values (name and size) in it. Initially I tried to use setName() and setSize() inside the for loop on the element, but after it didn't work and after reading other related questions, I assigned the values to temporary object before the loop and the used the iterator's set method to replace current element. But still no success and it even seems it never gets that far because the exception comes after line 5...
The problem is presumably that this line:
addCustomer();
is trying to modify customers while you're in the middle of iterating over it. This isn't allowed.
And anyway, it seems like a logic error: presumably you want to call addCustomer only once, after the loop, if no customer had the right tagID, but your current code tries to call addCustomer for each customer with with the wrong tagID. So you need to use a boolean variable during the loop to keep track of whether any customer matched, and then, after the loop, call addCustomer if appropriate.
ConcurentModificationException does not always indicate that an object has been concurrently modified by a different thread.
In your case the problem might be in following (guessing by addCustomer method): you are getting iterator of collection and then modifiying this collection. Because collection is modified, iterator becomes invalid and exception is thrown.
My suggestion will be create temproray list of customers which will you will append to your original customer list, when your iteration finished.
As mentioned in javadocs:
if a thread modifies a collection directly while it is iterating over
the collection with a fail-fast iterator, the iterator will throw this
exception.
I guess it is occurring after a call to addCustomer() which modifies the customers object. You can either hold the newly added objects in a different collection until end of the loop or break out of the loop and restart after adding.
I've got a very strange error, that would like to share with you.
I've the following code (simplified):
public ArrayList<String> al = new ArrayList<String>();
public void doSomething() {
int size = al.size();
for(int i=0; i<size; i++) {
if (al.get(i) != null) {
System.out.println(al.get(i));
String sPath = al.get(i);
File fFile = new File(sPath);
fFile.delete(); // Simplified. It has some error checking
}
}
}
I have one error, saw in the production environment:
java.lang.IndexOutOfBoundsException: Index: 1, Size: 0
at java.util.ArrayList.RangeCheck(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at MYCLASS.soSomething(MICLASS.java:1944)
[...]
Line 1944 is if (al.get(i) != null) {.
What! How can it raise IndexOutOfBound?!
The problem is that the error does not reproduce. I've been able to raise it only once in the dev environment, but trying to reproduce it was not possible (it dit not raise again)... so no way to look for a pattern in the error.
So my only option is simple: read the code and use the brain.
So I browse the code of java.util.ArrayList.get():
public class ArrayList<E> [...]{
public E get(int index) {
RangeCheck(index);
return (E) elementData[index];
}
private void RangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException("Index: "+index+", Size: "+size);
}
}
So it throws the exception because index >= size... How is it possible? The for() sweeps from 0 to size-1... It is impossible! It cannot raise the error!
Wait a second! This code is not thread-safe. Maybe another thread is calling clear() or remove*() on the ArrayList... Studying the code, it is not possible. So I run it, set a breakpoint on line 1944 and watch the threads in that moment, and effectively, the other running threads have nothing to do with this issue.
Any other clue?
Kernnigan & Pike: "Debugging [...]Something impossible occurred, and the only solid information is that it really did occur."
I see the following candidates how this happens:
something in your loop changes the value of i.
something in your loop changes the size of al, possibly something removing elements.
something is replacing your collection with a different collection.
I have seen cases where the loop was constructed in a way so the body gets even executed once in the case of an empty collection. Although that seems unlikely with a for loop as described.
An idea for debugging this: replace the list with your own implementation which logs every access to it, and delegating all the real functionality to a standard implementation.
If needed it can print the stack trace of an freshly created exception in order to identify the place it is called from. It can even throw an exception when it gets accessed from a different thread.
Everyone is suggesting that you're removing elements from the Array. The solution to your problem is to use an Iterator, which allows you to iterate through an entire Collection, but still allow you to modify that Collection.
You probably remove elements from your ArrayList in your for loop, therefore decrementing its original size which is used to exit this loop!
How sure are you that your simplified code exactly replicates the production code? To my mind it's impossible for your simplified code to raise IndexOutOfBoundsException because the list is empty so the for loop should never be processed. Are you modifying the contents of the array list in the loop?
Another possibility is that another thread is modifying the list while your code above is scanning it.
If you want something better than guesses, you need to show us either the relevant production code, or create a simplified version that actually exhibits the same problem when you run it.
Studying the code, it is not possible.
Clearly is is possible, otherwise you wouldn't have observed it.
Thanks everybody for the answers. Most of the suggestions are based on:
A) The loop is modifying al or i.
B) Another thread is modifying al.
c) Another thread is replacing al.
Since I know A is not the case, I'll bet that in some cases another thread is modifying/replacing al. Since I cannot make it fail in a pattern, such thread may be running only in certain situations, such as error conditions. While the code in the loop is pretty simple, the application is not at all small, with abuse of singletons and getter/setters, and it hardens the debugging, so I wouldn't be surprised of it.
That's the same that I suspected (except C, that I had not though of), but you confirmed that this is the only possible cause. Thanks for your help.