Java Array Indexing - java

class anEvent{
String number;
String dueTime;
}
public static void main(String args[]) {
int x = args.length / 2;
int y = args.length;
anEvent [] order = new anEvent [x];
for(int i=0; i<x; i++){
if(i==0){
order[i].number = args[0]; //Line(#)
order[i].dueTime = args[1];
} else if ( i % 2 == 0){
order[i].number = args[i];
order[i].dueTime = args[i];
} else if ( i % 2 != 0){
order[i].number = args[i+1];
order[i].dueTime = args[i+1];
} else if ( i == x -1){
order[i].number = args[x-1];
order[i].dueTime = args[x-1];
}
}
Java complains that a Null Pointer exceptuion is present at line # in the above snippet.
What's the matter?
ps: I know that the snippet can be cleaned up but there should be no problem at all on line #

When an array is created, all the array elements are null. In your case, you need to fill the array with new anEvent() instances.

Make the first line of your for-loop:
order[i] = new anEvent();
As is, you are not initializing anything in the array (they're all null), so when you try to access the fields you get that exception.

Since you mention that it "can be cleaned up", I took the liberty of so doing:
public class Thing {
private String number;
private String dueTime;
public Thing(String number, String dueTime) {
this.number = number;
this.dueTime = dueTime;
}
public static void main(String args[]) {
int x = args.length / 2;
Thing[] order = new Thing[x];
for (int i = 0; i < x; i++) {
if (i == 0) {
order[i] = new Thing(args[0], args[1]);
} else if (i % 2 == 0) {
order[i] = new Thing(args[i], args[i]);
} else if (i % 2 != 0) {
order[i] = new Thing(args[i + 1], args[i + 1]);
}
}
}
}
"anEvent" doesn't conform to the capitalized camel-case Java standard, so I renamed it. "Thing" isn't particularly meaningful, but there isn't much to work with here. The final else if clause can never be reached, because i % 2 either is or is not equal to zero, so I dropped it. And, of course, I'm creating new Things, which avoids the problem of the nulls. Enjoy.

NullPointerException means that you attempted to add a value or execute a method to something that turn out to be a null.
In Java object references can have assigned ... well, objects and null
When they have null assigned this exception is thrown:
Object o = null;
o.toString(); // <- NullPointerException ( think of null.toString() )
Arrays, are objects also. When you create an array with a size, all the "boxes" inside the array contain null as reference.
So:
Object[] array = new Object[10];
Creates something similar to the following:
[null,null,null,null,null,null,null,null,null,null]
That's why, when you execute:
array[0].toString(); // or order[i].number in your specific example...
You get that exception, because the effect is exactly the same as:
null.toString(); // or null.number <-- NullPointerException.
To solve this problem, you have to assign a valid object reference to that position into the array:
for(int i=0; i<x; i++){
order[i] = new anEvent();
...
...
I hope this helps.
Final note. In Java classes names start with upper case, so your class should've really be:
class AnEvent {
....
And finally, most of the java source code is indented using 4 spaces.

You hasn't created any anEvent instance, defining an array (order[]) you are not creating default values for it.
and also there are more simple array for your case:
List events = new ArrayList(x);
for(int i=0; i<y; i+=2){
anEvent event = new anEvent();
anEvent.number = args[i];
anEvent.dueTime = args[i+1];
events.add(event);
}
anEvent[] order = events.toArray();

Related

Looping through two separate if statements

The code below is a simplified version of a method I am working on for a java project. The method will sort through a list of items(two different categories), in this case 0,s and 1's. The code reads through an array of numbers stops at either 0 or 1 and then prints out both the 0 or one and the string of numbers following the 0 or 1. If a preceding string is a 1 or a zero then it will stop and switch to another if statement. However it only executes each statement once. However there is more in the array that it needs to read through and organize. I would like to set up some sort of loop so that it loops through the set of if statements until it has read through the entire array.
public class tester
{
public static void main(String[] args )
{
String flags[] = {"0","23","25","34","1","9","12","13","0","67","2","43"};
String array[] = new String[flags.length];
String zeros [] = new String[array.length];
String ones[] = new String[array.length];
int i,j,k,h;
int count = 0;
for (i = 0; i<flags.length; i++)
{
if (flags[i].equals("0"))
{
for (j=0; !flags[j].equals("1") ; j++)
{
count = j+1;
array[j] = flags[j];
zeros[j] = flags[j];
}
} else
if (flags[count].equals("1"))
{
j = 0;
for(k=count; !flags[k].equals("0");k++)
{
array[k] = flags[k];
j++;
ones[j-1] = flags[k];
}
}
}
for(i=0; i<zeros.length; i++)
{System.out.println(zeros[i]);}
System.out.println();
for(i=0; i<ones.length; i++)
{System.out.println(ones[i]);}
}
}
What it prints out now:
0
23
25
34
null
null
null
null
null
null
null
null
1
9
12
13
null
null
null
null
null
null
null
null
String flags[] = {"9","0","23","25","34","1","9","12","13","0","67","2","43"};
String array[] = new String[flags.length];
String zeros [] = new String[array.length];
String ones[] = new String[array.length];
int i;
boolean addingZeroes = false;
boolean addingOnes = false;
int zeroCount = 0;
int onesCount = 0;
for (i = 0; i<flags.length; i++) {
if (flags[i].equals("0")) {
zeros[zeroCount] = flags[i];
zeroCount++;
addingZeroes = true;
addingOnes = false;
} else if (flags[i].equals("1")) {
ones[onesCount] = flags[i];
onesCount++;
addingZeroes = false;
addingOnes = true;
} else if (addingZeroes) {
zeros[zeroCount] = flags[i];
zeroCount++;
} else if (addingOnes) {
ones[onesCount] = flags[i];
onesCount++;
}
}
for(i=0; i<zeroCount; i++) {
System.out.println(zeros[i]);
}
System.out.println();
for(i=0; i<onesCount; i++) {
System.out.println(ones[i]);
}
Hey, couple things were wrong. Basically, you need a little state machine where you need to know whether you are in the midst of storing the sequence after a 1 or a 0. I used the boolean values (eg addingZeroes) for that.
Then, you need to separately keep track of your element count (eg zeroCount) for each of the storage arrays. You might have 20 digits after a 0 and just 2 after a 1.
Finally, at the end, your length of your storage arrays is not what you want - you want the amount of values you ended up storing. That's why you got all those "nulls".
One other thing I noticed is that your j value is initialized always to 0 in the 0 block, so you would always be using the lowest values of the start array.

Detail formatter error: java.util.Arrays cannot be resolved to a type

I have developed a BlackBerry application where in I am reading in a HEX String values. The values returned are as follows:
String result = response.toString();
where result is:
["AC36C71DF3CB315A35BFE49A17F483B6","CF5B717ACC460E3C4545BE709E9BCB83","E1EE334738CA4FA14620639DD6750DC3","DD40E2822539C2184B652D1FC3D2B4E6","6AF4B1EAC8D8210D64A944BFD487B9F2"]
These are passed into the following split method to separate the values. The method is as follows:
private static String[] split(String original, String separator) {
Vector nodes = new Vector();
int index = original.indexOf(separator);
while (index >= 0) {
nodes.addElement(original.substring(0, index));
original = original.substring(index + separator.length());
index = original.indexOf(separator);
}
nodes.addElement(original);
String[] result = new String[nodes.size()];
if (nodes.size() > 0) {
for (int loop = 0; loop < nodes.size(); loop++) {
result[loop] = (String) nodes.elementAt(loop);
System.out.println(result[loop]);
}
}
return result;
}
The above array is passed is as the String original in the method. This part is working fine. However, when a single value is passed in as String original, i.e. ["6AF4B1EAC8D8210D64A944BFD487B9F2"], I get an error :
Detail formatter error:java.util.Arrays cannot be resolved to a type.
Please help !!! The values posted above are exact values as read including the parenthesis [] and quotations ""
The Blackberry libraries are based on Java ME and not Java SE. In Java ME some classes have been removed to reduce the runtime footprint such as the Arrays class.
Take a look at the Blackberry JDE java.util package, see there is no Arrays class. So in your code you cannot use methods coming from the Arrays class, you must found a workaround or implement the feature yourself.
Try this split method -
public static String[] split(String strString, String strDelimiter) {
String[] strArray;
int iOccurrences = 0;
int iIndexOfInnerString = 0;
int iIndexOfDelimiter = 0;
int iCounter = 0;
//Check for null input strings.
if (strString == null) {
throw new IllegalArgumentException("Input string cannot be null.");
}
//Check for null or empty delimiter strings.
if (strDelimiter.length() <= 0 || strDelimiter == null) {
throw new IllegalArgumentException("Delimeter cannot be null or empty.");
}
if (strString.startsWith(strDelimiter)) {
strString = strString.substring(strDelimiter.length());
}
if (!strString.endsWith(strDelimiter)) {
strString += strDelimiter;
}
while((iIndexOfDelimiter = strString.indexOf(strDelimiter,
iIndexOfInnerString)) != -1) {
iOccurrences += 1;
iIndexOfInnerString = iIndexOfDelimiter +
strDelimiter.length();
}
strArray = new String[iOccurrences];
iIndexOfInnerString = 0;
iIndexOfDelimiter = 0;
while((iIndexOfDelimiter = strString.indexOf(strDelimiter,
iIndexOfInnerString)) != -1) {
strArray[iCounter] = strString.substring(iIndexOfInnerString,iIndexOfDelimiter);
iIndexOfInnerString = iIndexOfDelimiter +
strDelimiter.length();
iCounter += 1;
}
return strArray;
}

Java for loop by value or by reference

I figured out a a problem in my Code. First the code:
public class Main {
/**
* #param args
*/
public static void main(String[] args) {
String[] blablubb = { "a", "b", "c" };
for(String s : blablubb) {
s = "over";
}
printArray(blablubb);
for (int i = 0; i < blablubb.length; i++) {
blablubb[i] = "over";
}
printArray(blablubb);
}
public static void printArray(String[] arr) {
for( String s : arr ) {
System.out.println(s);
}
}
}
The output is:
a
b
c
over
over
over
I assumed the first loop would also overwrite the String in the array. So the output would be over in any case. It seems it creates a copy of the value instead creating a reference.
I never perceived this. Am I doing it wrong? Is there an option to create a reference instead?
//Edit:
Seems like everybody knows about that except me. I'm from C background and doesn't pay enough attention to the term reference which is very different to C.
Fortunately it took me just 10 minutes to figure this out (this time).
This:
for (String s : blablubb) {
s = "over";
}
Is equal to this:
for (int i = 0; i < blablubb.length; i++) {
String s = blablubb[i];
s = "over";
}
This creates a temporary String with a copy of the value from array and you change only the copy. That's why blablubb[] content stays untouched.
If you want to change values in the array, just use your second option:
for (int i = 0; i < blablubb.length; i++) {
blablubb[i] = "over";
}
And, by the way, you can print an array with just one line:
System.out.println(Arrays.toString(blablubb));
Your for(String s : blablubb) loop is equivalent to the following code:
for(int i = 0; i < blablubb.length; i++ ) {
String s = blablubb[i];
s = "over";
}
Hopefully, from this you can see that all you are doing is reassigning a different value to s without changing blablubb[i]. This explains the output you see.
The for-each loop don't modify the objects contained in the Collection of objects it's iterating over. It's passing the value not the reference.
s = "over";
just changes the reference of s and not the String in the array.
blablubb[i] = "over";
changes the value stored at ith location in the array
for(String s : StringArray)
{
}
is like
for(int i = 0; i < StringArray.length; i++)
{
String s = StringArray[i];
}
When you want to do a low level optimization, know how, you have to look inside Java code and inside byte-code either(compiled code)
for(String s : blablubb) {
s = "over";
}
is equals with:
for (int i = 0; i < blablubb.length; i++) {
String s = blablubb[i];
s = "over";
}
and that's why the output as how it is.

Printing string array also prints null

When I am printing contents of a string array the output is printing 'null' as well. I am not sure what's wrong with this. Here is the output, what I expect is the output without 'null'
null(wa?>=0)nullnull*(wo?>=0)nullnull*(4*wa?+7*wo?>=50)nullnull*(d1=10)nullnull*((d2=1)+(k=2))nullnull
Thanks and appreciate your help. I would say my skill in Java in beginner level and I started two weeks back.
Here is the actual code:
String[] arrStr = new String[50];
int countStr = 0;
for (int i = 0; i < para.length; i++) {
if (para[i] == '(') {
count = count + 1;
}
if (para[i] == ')') {
count = count - 1;
}
if (count > 0) {
arrStr[countStr] = arrStr[countStr] + para[i];
} else {
if (para[i] == ')') {
arrStr[countStr] = arrStr[countStr] + para[i];
countStr += 1;
} else {
countStr += 1;
arrStr[countStr] = arrStr[countStr] + para[i];
// System.out.println(para[i]);
}
}
}
System.out.println(countStr);
for (int i = 0; i < countStr; i++) {
System.out.print(arrStr[i]);
}
Before this part, I am reading the following string from a word document:
(wa?>=0)AND(wo?>=0)AND(4*wa?+7*wo?>=50)AND(d1=10)AND((d2=1)+(k=2))
I think the problem may be due to the line:
arrStr[countStr] = arrStr[countStr] + para[i];
Since arrStr[countStr] is null initially and I add an element to it, it saves it as null+para[i]. Do you think it is possible?
Like when I try: System.out.println(arrStr[0]); I get the output as
null(wa?>=0)
System.out.println(null + "Bla");
prints nullBla. A null represented as String is "null". The issue here is that initially all your String[] is made of null. You need to initialize them first. Typically,
Arrays.fill(arrStr, "");
Should do.
If any element in arrStr is null while printing, it will print that faithfully.
Without knowing specifics in your code, you can either ensure that no element in your array becomes null (ensure that the lengths match up and you're not skipping element in arrStr, or check for null before printing the element.
You don't initialize the values of the arrStr array, you just allocate size for it, so each element of the array is null. When you assign a value to an element of the array, you concatenate its value (which is null) with the value of para[i].
You should initialize your array before using it:
String[] arrStr = new String[50];
for (int i = 0; i < arrStr.length; i++) {
arrStr[i] = "";
}

List collections interface in java

Please find below a function in my code:
private static List<String> formCrfLinesWithMentionClass(int begin, int end, String id,
List<String> mList, int mListPos, List<String> crf) {
List<String> crfLines = crf;
int yes = 0;
mListPosChanged = mListPos;
//--------------------------------------------------------------------------
for (int crfLinesMainIter = begin; crfLinesMainIter < end; ) {
System.out.println(crfLines.get(crfLinesMainIter));
//---------------------------------------------------------------------------
//the total number of attributes without orthographic features
//in a crfLine excluding the class attribute is 98
if (!crfLines.get(crfLinesMainIter).equals("") && crfLines.get(crfLinesMainIter).split("\\s").length == 98) {
//in mList parenthesis are represented by the symbol
//in crfLines parenthesis are represented by -LRB- or -RRB-
//we make a check to ensure the equality is preserved
if(val.equals(crfLines.get(crfLinesMainIter).split("\\s")[0])) {
yes = checkForConsecutivePresence(crfLinesMainIter, mList, mListPos, id, crfLines);
if (yes > 0) {
mListPosChanged += yes;
System.out.println("formCrfLinesWithMentionClass: "+mListPosChanged);
for (int crfLinesMentionIter = crfLinesMainIter;
crfLinesMentionIter < crfLinesMainIter + yes;
crfLinesMentionIter++) {
String valString = "";
if (crfLinesMentionIter == crfLinesMainIter) {
valString += crfLines.get(crfLinesMentionIter);
valString += " B";
crfLines.add(crfLinesMentionIter, valString);
}
else {
valString += crfLines.get(crfLinesMentionIter);
valString += " I";
crfLines.add(crfLinesMentionIter, valString);
}
}
crfLinesMainIter += yes;
}
else {
++crfLinesMainIter;
}
}
else {
++crfLinesMainIter;
}
}
else {
++crfLinesMainIter;
}
}
return crfLines;
}
The problem I face is as follows:
crfLines is a List collections interface.
When the for loop (between //-----) starts out, the crfLines.get(crfLinesMainIter) works fine. But once, it enters into the if and other processing is carried out on it, even though "crfLinesMainIter" changes the crfLines.get(crfLinesMainIter) seems to get a certain previous value. It does not retrieve the actual value at the index. Has anyone faced such a scenario? Would anyone be able to tell me why this occurs?
My actual question is, when does it occur that even though the indexes might be different a list.get() function still retrieves a value from before which was at another index?
For example:
List crfLines = new LinkedList<>();
if crfLinesMainIter = 2
crfLines.get(crfLinesMainIter) brings me a value say 20 and this value 20 satisfies the if loop condition. So then further processing happens. Now when the for loop executes the values of crfLinesMainIter changes to say 5. In this case, crfLines.get(5) should actually bring me a different value, but it still brings me the previous value 20.
(Not an answer.)
Reworked (more or less) for some modicum of readability:
private static List<String> formCrfLinesWithMentionClass(int begin, int end, String id, List<String> mList, int mListPos, List<String> crf) {
List<String> crfLines = crf;
mListPosChanged = mListPos;
int i = begin;
while (i < end) {
if (crfLines.get(i).equals("") || (crfLines.get(i).split("\\s").length != 98)) {
++i;
continue;
}
if (!val.equals(crfLines.get(i).split("\\s")[0])) {
++i;
continue;
}
int yes = checkForConsecutivePresence(i, mList, mListPos, id, crfLines);
if (yes <= 0) {
++i;
continue;
}
mListPosChanged += yes;
for (int j = i; j < i + yes; j++) {
String valString = crfLines.get(j);
valString += (j == i) ? " B" : " I";
crfLines.add(j, valString);
}
i += yes;
}
return crfLines;
}
What is mListPostChanged? I find it confusing that it's being set to the value of a parameter named mListPos--it makes me think the m prefix is meaningless.
What is val in the line containing the split?

Categories