Nullpointer Acess message in Java - java

I have created a method to parse a JSON object and to return an array of string.
private String[] getAttributesfromJson(JSONObject attacheddataattributejson) {
String returnjsonArray[] = null;
JSONArray subcatarray = attacheddataattributejson.optJSONArray("subcatAttributes");
if(subcatarray!=null){
for(int i=0;i<subcatarray.length();i++)
{
returnjsonArray[i]=subcatarray.getJSONObject(i).optString("name");
}
}
return returnjsonArray;
}
But my eclipse is showing an warning on returnjsonArray[i] that this can only be null at this pos. But I have a null check for subcatarray also. Please help.

You initialize your returnjsonArray[] to null and try to access it without having ever initialized it.
Java does no magic with null references; what is more, arrays are not dynamically allocated in Java. If you want that, use a List (which you should initialize as well), and return this list's .toArray().

See this line
String returnjsonArray[] = null;
You forgot to initialize it.
You won't get anything from a basket when you did'nt fill it before.

you can use the following code.
private String[] getAttributesfromJson(JSONObject attacheddataattributejson) throws JSONException {
List<String> returnjsonArray = new ArrayList<String>();
JSONArray subcatarray = attacheddataattributejson.optJSONArray("subcatAttributes");
if (subcatarray != null) {
for (int i = 0; i < subcatarray.length(); i++) {
returnjsonArray.add(subcatarray.getJSONObject(i).optString("name"));
}
}
return (String[]) returnjsonArray.toArray();
}

Related

Removing null values from array and getting it from the method in Java

I'm trying to remove null values from an array, and returning them to do some other stuff with the new values. However, I'm confused about how to get the updated array.
This is the null removal code.
String[] removeNull(String[] nullArray) {
int nullCounter = 0;
//checking if any is null
for(int i = 0; i < nullArray.length; i++) {
if(nullArray[i]==null) {
nullCounter++;
}
}
String[] noNulls = new String[nullArray.length-nullCounter];
if(nullCounter>0) {
//make a non null array
for(int i = 0, j = 0; i <noNulls.length; i++) {
if(nullArray[i]!=null) {
noNulls[j] = nullArray[i];
j++;
}
}
}
return noNulls;
}
I'm pretty sure that is already correct (Please correct me if I'm wrong). Then, I called it inside a constructor.
public theBoundary(String[] bounds){
removeNull(bounds);
}
After I called removeNull(bounds), will the value of the new array be stored in the array bounds? Or will it be stored in the array noNull? I can't seem to find where the new values are stored.
Thank you, and please tell me if there are mistakes. I've been going around this for half an hour now.
Note: If possible, please don't give me answers that include importing something else. Vanilla Java would be preferred.
removeNull() returns the array noNulls, created inside the method. Currently, in theBoundary(), you simply call removeNull(bounds), but do not assign it to a variable. The newly created null-free array is created, not assigned, and immediately garbage collected.
If you wish to do something with your non-null-containing array (which I assume you do), do this:
public theBoundary(String[] bounds) {
String[] withoutNulls = removeNull(bounds);
doSomething(withoutNulls); // whatever you need here
}
Note, unless you really have to use an array, consider using a List or even a Stream.
List example:
List<String> list = ... // from somewhere else
list.removeIf(s -> s == null);
doSomething(list);
Stream example:
Stream<String> stream = ... //from somewhere else
stream.filter(s -> s != null);
doSomething(stream);
EDIT
Even if you do really need arrays, the following will also work:
String[] noNulls = (String[]) Arrays.stream(inputArray).filter(Objects::nonNull).toArray();
I don't think there is any need to iterate the array twice!
You can instead use a stream on array and filter the indexes without that are NOT NULL.
Also, you can do this without needing to create the removeNull method, and do this directly in your theBoundary method.
Here is how your code will look like:
String[] arrayWithoutNull = Arrays.stream(bounds).filter(Objects::nonNull).toArray(String[]::new)
I hope this solves your problem.
Do you mean this?
public theBoundary(String[] bounds){
String[] cleanedBounds = removeNull(bounds);
}
You are not doing it inplace so you need to assign it back to a new array

Return value from method java

I have a program in java that I wrote to return a table of values. Later on as the functions of this program grew I found that I would like to access a variable within the method that isn't returned but I am not sure the best way to go about it. I know that you cannot return more than one value but how would I go about accessing this variable without a major overhaul?
here is a simplified version of my code:
public class Reader {
public String[][] fluidigmReader(String cllmp) throws IOException {
//read in a file
while ((inpt = br.readLine()) != null) {
if (!inpt.equals("Calls")) {
continue;
}
break;
}
br.readLine();
inpt = br.readLine();
//set up parse parse parameters and parse
prse = inpt.split(dlmcma, -1);
while ((inpt = br.readLine()) != null) {
buffed.add(inpt);
}
int lncnt = 0;
String tbl[][] = new String[buffed.size()][rssnps.size()];
for (int s = 0; s < buffed.size(); s++) {
prse = buffed.get(s).split(dlmcma);
//turns out I want this smpls ArrayList elsewhere
smpls.add(prse[1]);
//making the table to search through
for (int m = 0; m < prse.length; m++) {
tbl[lncnt][m] = prse[m];
}
lncnt++;
}
//but I return just the tbl here
return tbl;
}
Can anyone recommend a way to use smpls in another class without returning it? Is this perhaps when you use a get/set sort of setup?
Sorry if this seems like an obvious question, I am still new to the world of modular programming
Right now you have this tbl variable. Wrap it in a class and add the list to the class.
class TableWrapper {
// default accessing for illustrative purposes -
// setters and getters are a good idea
String[][] table;
List<String> samples;
TableWrapper(String[][] table, List<String> samples) {
this.table = table;
this.samples = samples;
}
}
Then refactor your method to return the wrapper object.
public TableWrapper fluidigmReader(String cllmp) throws IOException {
// your code here
String tbl[][] = new String[buffed.size()][rssnps.size()];
TableWrapper tw = new TableWrapper(tbl,smpls);
// more of your code
return tw;
}
Then later in your code where you were going
String[][] tbl = fluidigmReader(cllmp);
You instead go
TableWrapper tw = fluidigmReader(cllmp);
String[][] tbl = tw.table;
List<String> smpls = tw.samples;
If you had used a dedicated class for the return value (such as the TableWrapper mentioned in another answer), then you could add additional fields there.
That is the good thing about classes - they can be extended. But you cannot extend String[][] in Java.
You can set a field, instead of a local variable, which you can retrieve later with a getter. You want to avoid it unless it is needed, but in this case it is.
You can use class(Inside Reader class) variable for this. But make sure that it's read/write is synchronized

null pointer exception in array

I am getting a null exception error from this segment of code and I am not sure what causing it. The array itemcatalog has being populate for i =0 to 8. I am new to java so any assistance will be greatly appreciated. The error message points to the line of the while statement. Thanks
public class ItemCatalog {
private static ItemCatalog instance = new ItemCatalog();
private Item itemCatalog[] = new Item[9];
private ItemCatalog(){
};
public static synchronized ItemCatalog getInstance() {
return instance;
}
public void populateCatalog()
{
itemCatalog[0] = new Item("bb","Baked Beans",new BigDecimal("0.35"));
itemCatalog[1] = new Item("cf","Cornflakes",new BigDecimal("1.00"));
itemCatalog[2] = new Item("s0","Sugar",new BigDecimal("0.50"));
itemCatalog[3] = new Item("tb","Tea Bags",new BigDecimal("1.15"));
itemCatalog[4] = new Item("ic","Instant Coffee",new BigDecimal("2.50"));
itemCatalog[5] = new Item("b0","Bread",new BigDecimal("0.50"));
itemCatalog[6] = new Item("s0","Sausages",new BigDecimal("1.30"));
itemCatalog[7] = new Item("e0","Eggs",new BigDecimal("0.75"));
itemCatalog[8] = new Item("m0","Milk",new BigDecimal("0.65"));
}
public BigDecimal getPrice(String itemCode)
{
int i = 0;
while (!itemCode.equals(itemCatalog[i].getItemCode()))
{
i++;
}
BigDecimal itemPrice = itemCatalog[i].getItemprice();
return itemPrice;
}
}
I solved the issue. I was populating the catalog in the main class which was giving the null exception error. I instantiate it in the jframe instead and it works. The follow code solved the issue, but is this the best place to populate the catalog?
private void saleButtonActionPerformed(java.awt.event.ActionEvent evt) {
String itemCode = this.itemCodeinput.getText();
int itemQuantity =Integer.parseInt(this.itemQuantityinput.getText());
ItemCatalog catalog = ItemCatalog.getInstance();
catalog.populateCatalog();
BigDecimal price = catalog.getPrice(itemCode);
itemCostoutput.setText(price.toString());
}
If your itemCode doesn't match any entries in your itemCatalog, then eventually
while (!itemCode.equals(itemCatalog[i].getItemCode()))
{
i++;
}
will increment i to 11, in which case itemCatalog[11] is either empty or out of bounds.
If addition, you should use a for loop to iterate through the itemCatalog:
for (int i = 0; i < itemCatalog.length; i++) {
if (itemCode.equals(itemCatalog[i].getItemCode()) {
return (BigDecimal) itemCatalog[i].getItemprice();
}
}
return null // you can change this from null to a flag
// value for not finding the item.
From the comments, it's clear the design isn't sound.
Here's a possible solution :
public BigDecimal getPrice(String itemCode) {
for (int i=0; i<itemCatalog.length; i++) { // not going outside the array
if (itemCatalog[i].getItemCode().equals(itemCode)) { // inversing the test to avoid npe if itemCode is null
return itemCatalog[i].getItemprice();
}
}
return null; // default value
}
This supposes your array is correctly filled with itemCatalogs having an itemCode.
How do you end your loop?
Seems that the loop will keep going until i is 10. Then your will have exceeded the limit.
Unless this is a uni assignment where you have to use arrays, I'd also suggest using a map, rather than an array. This way your lookup will be the same time, whether your collection has 100,000 entries or 10.
You will also reduce risk of NPE or ArrayOutOfBounds exception
See http://docs.oracle.com/javase/1.4.2/docs/api/java/util/HashMap.html
When adding the object use the item code as the key. Then lookup by the key.
The cost of using a map is increased memory usage.

Having trouble with accessing array data from one class to another

I am having some trouble with passing data of an array from one class to the next.
edits
I am now no longer getting the error, and my code compiles, but as I had been warned, I got null for every element of the array. Now that I have taken out the static modifiers though, it still gives me null. I have also updated the code.
Here is the class where the array is created.
public class AssignSeat {
String[] arrangement = new String[12];
public void SeatStart() {
arrangement[0] = "Collins";
arrangement[2] = "Faivre";
arrangement[3] = "Kinnard";
arrangement[6] = "Morgans";
arrangement[7] = "Rohan";
arrangement[8] = "Shatrov";
arrangement[9] = "Sword";
arrangement[11] = "Tuckness";
System.out.format("%-15s%-15s%n", "seat", "passenger");
for (int i=0; i<arrangement.length; i++) {
System.out.format("%-15s%-15s%n", i+1, arrangement[i]);
}
}
public String[] getArrangement() {
return arrangement;
}
public void setArrangement(String[] arrangement) {
this.arrangement = arrangement;
}
}
and here is the method trying to access the information. It is specifically the for loop that I need help with so Ignore other areas where there are mistakes. Thank you.
public void actionPerformed(ActionEvent event) {
Scanner scanner = new Scanner(System.in);
AssignSeat seat = new AssignSeat();
if(event.getSource() instanceof JButton){
JButton clickedButton = (JButton) event.getSource();
String buttonText = clickedButton.getText();
if (buttonText.equals("first class")) {
entername.setVisible(true);
seatnum.setVisible(true);
confirmed.setVisible(true);
inputline.setVisible(true);
outputline.setVisible(true);
if ((seat.arrangement[1] == null)) {
System.out.println(seat.arrangement[0]);
System.out.println(seat.arrangement[2]);
two.setForeground(Color.green);
}
} else if (buttonText.equals("coach")) {
//System.out.println("so does this!");
entername.setVisible(true);
seatnum.setVisible(true);
confirmed.setVisible(true);
inputline.setVisible(true);
outputline.setVisible(true);
if ((seat.arrangement[4] == null)) {
five.setForeground(Color.green);
}
if ((seat.arrangement[5] == null)) {
six.setForeground(Color.green);
}
if ((seat.arrangement[10] == null)) {
eleven.setForeground(Color.green);
}
}
}
}
The problem lies in the fact that the array was declared as static, but the initialization code for it is in the constructor. Remove all the static modifiers in the original code, and replace this part:
if (AssignSeat.getArrangement()[1].equals("null"))
With this:
AssignSeat assign = new AssignSeat();
if (assign.getArrangement()[1] == null)
Also notice that "null" is not a null value, use null (without quotes) for that.
A different approach would be to leave the array as an static member, but initialize it statically, like this:
private static String[] arrangement = new String[12];
static {
arrangement[0] = "Collins";
arrangement[2] = "Faivre";
arrangement[3] = "Kinnard";
arrangement[6] = "Morgans";
arrangement[7] = "Rohan";
arrangement[8] = "Shatrov";
arrangement[9] = "Sword";
arrangement[11] = "Tuckness";
}
In that case, this would work:
if (AssignSeat.getArrangement()[1] == null)
But I still believe that making the array static is going to be problematic if several instances of the class happen to be modifying its contents.
Replace
if (AssignSeat.getArrangement()[1].equals("null"))
with
if (AssignSeat.getArrangement()[1] == null)
If the value is null, you can't invoke methods (like equals) on it. You need to compare the value directly to null, which is a constant rather than a string.
Ok, I'm a bit confused as to what you're trying to do in the first class. You are initializing a static array from an instance method...
In other words, the String values in the array will be null until you call SeatStart from an instance of the class.
Try to initialize the String array from the static constructor for AssignSeat to make sure it has been initialized before you use it: http://www.snippetit.com/2009/05/java-static-variables-static-methods-and-static-constructor/
You are trying to use an attribute of a class, without instantiating the object first. Until you call a default/user-defined constructor, there is no memory dedicated to the attribute of that object.
Even though you manage to call the method you are using a static method, which can be called without an instance of the object being required.
Create a constructor for the object (or use a default constructor) and then you will be able to access your attribute because your object will be on the heap and have memory allocated for the string[].
Simply define the SeaStart as an Array.
public String[] SeatStart() {
arrangement[0] = "Collins";
arrangement[2] = "Faivre";
arrangement[3] = "Kinnard";
return arrangement;
}
For convinience, make a new array to copy the array from AssignSeat class. Then retrieve the value from that array.
public void actionPerformed(ActionEvent event) {
AssignSeat seat = new AssignSeat();
String[] foo = seat.SeatStart();
System.out.println(foo[0]);
System.out.println(foo[1]);
System.out.println(foo[2]);
}
Though you can acces it also with:
System.out.println(seat.SeatStart()[0]);
The result would be:
Collins
null
Faivre
and that 'null' is because apparently you haven't allocate a value for arrangement[1] :-)
But in the end, it works.

How many dimensions in an array with no value

I'm a little lost (still working with Ron Jeffries's book). Here's a simple class:
public class Model{
private String[] lines;
public void myMethod(){
String[] newLines = new String[lines.length + 2];
for (i = 0, i <= lines.length, i++) {
newLines[i] = lines[i];
}
}
}
I have another class that initializes Model, and an empty array, by setting myModel = new String[0]. When I invoke myModel.myMethod(), I get a subscript out of range error. Looking at the debugger, what I see is that myModel.lines has zero dimensions and zero length. Shouldn't it have a dimension and length of 1? Granted the value of lines[0] is null, but the array itself shouldn't be, should it?
Any thoughts truly appreciated.
Randy
I think your example is probably not the same as your actual code based on your description. I think the problem is that arrays are zero-based and thus an array initialized as:
string[] lines = new string[0];
has no elements.
You need to change your loop so that you check that the index is strictly less than the length of the array. As others have indicated you also need to make sure that the array itself is not null before trying to reference it.
My take on your code:
public class Model{
private String[] lines = new string[0];
public Model( string[] lines ) {
this.lines = lines;
}
public void myMethod(){
int len = 2;
if (lines != null) {
len = len + lines.length;
}
String[] newLines = new String[len];
for (i = 0, i < lines.length, i++) {
newLines[i] = lines[i];
}
}
}
lines will be null, so lines.length will throw an exception.
I believe your other class initializing "Model" won't help since Lines itself is private. In fact, whatever you are doing to Model is probably illegal in at least 30 states.
lines is initalized to null, check for null or initialize it in this way :
private String[] lines = new String[0];
You cannot initialize an instance of Model by setting it equal to a String array. I'm actually surprised that the compiler will let you even try.
If you really want Model to be initializable with an external array, you should make a Constructor for the Model class that will take as an argument the array. Then in the body of your constructor, set the value of lines to that value.
Example:
public class Model {
private String []lines;
public Model(String [] inLines)
{
lines = inLines;
}
}
Usage:
myStringArray = new String[0];
myModel = new Model(myStringArray);
Take a look at my answer here - I think this will get you the background you are looking for on the differences between array initialization in Java and C/C++.

Categories