Can't figure out why I am getting null values - java

The program is supposed to print out the amount of times each name has been selected (this is indicated by number of asterisks (*). I have most of the code working but for some reason the output contains two null values for each name and I am not sure how to fix the problem. Also if you have the time, I'm also struggling to find out which name has the most amount of asterisks. Here's an example output:
1: nullnull************************ Conner
2: nullnull********************************** John
etc...
(it does this for all 10 names)
public class RandomStudentsLab {
public static void main(String[] args){
//create an array with 10 students
String [] StudentList = new String[10];
String [] StarString = new String[10];
String [] FinalString = new String[10];
//add 10 names to the student list
StudentList[0] = "Conner";
StudentList[1] = "John";
StudentList[2] = "Alex";
StudentList[3] = "Robert";
StudentList[4] = "James";
StudentList[5] = "Carl";
StudentList[6] = "Sarah";
StudentList[7] = "Bob";
StudentList[8] = "Ethan";
StudentList[9] = "Chris";
//loop 250 times selecting each student randomly
for(int i=0; i<250; i++){
int randomNum = (int)((Math.random()*10));
for(int x=0; x<10; x++){
if(randomNum == x){
StarString[x] += "*";
}
}
}
for(int z=0; z<10; z++){
System.out.println((z+1)+": "+(FinalString[z] += StarString[z] + " "+StudentList[z]));
}
}
}

Elements in FinalString and StarString arrays are still not initialized. So with += operator its calling toString on the null element and prefix "null" to each string.

As mentioned by Karthik in his answer you never initialized (as in you never assigned values) the FinalString array. That is what is causing your error.
You can easily tell since your System.out.println() is printing:
Number : nullnull Stars Name
So clearly your issue is with FinalString, it is the only variable not printing correctly.
System.out.println((z+1)+": "+(FinalString[z] += StarString[z] + " "+StudentList[z]));
You are making the same mistake with the StarString array. You are lucky enough to get away with it in this case since you end up adding variables to StarString in your loop.
However, NOT initialising ANY variable is >>horrible<< practice. You never know what was previously stored in memory, this could lead to your variables being assigned some 'alien' data that was leftover on the memory by some other program. Secondly, and this is the issue in your question, if you forget to initialise you can run into null errors and such.
So as a matter of good coding practice always initialise your variables to something. Even if you are using the variable two lines later - it doesn't matter. When you create your variable assign it a value:
If it's an integer then 0 or -1. It's better if it's a value that won't occur in your program, so if you have an error in your code you can spot it easily because your integer will be -1 instead of x y z.
If it's a string then name it 'banana' or 'peanuts' or whatever.
If it's an object make sure you initialise all of the attributes
And so on...
P.S. Not sure if I came accross as harsh, but it's absolutely not my intention. Good coding practices are simply important and will be extremely helpful in the future.
Best of luck!
EDIT:
Little update to reflect your comment on another answer.
When you create FinalString here String [] FinalString = new String[10]; your are not assigning any values to it, unlike what you did with the names.
So when your code gets to the final for loop here:
for(int z=0; z<10; z++){
System.out.println((z+1)+": "+(FinalString[z] += StarString[z] + " "+StudentList[z]));
}
}
}
And you try to do a System.out.println() for FinalString[z], well FinalString[z] still does not have a value. At no point in your code did you write
FinalString[0] = "Banana";
So obviously it will print null instead.

Related

Why can't I print the String out of my multidimensional-Array?

I've read in other posts, that instead of writing just System.out.println(finalPressedKey);
you should write System.out.println(Arrays.toString((finalPressedKey)); because otherwise it will just return the location where the String is saved (as far as I understood it).
public static String PressedKey[] = new String[2000];
public static String[][] finalPressedKey = {{ "", "", "", "", "", "", "", "", "", "", "", "" }}; // 12
public static String FPK3;
public static void upcounter(KeyEvent e) {
for (int x = 0; x < PressedKey.length; x++) {
if (PressedKey[x] != null && PressedKey[x + counter] != null) {
//FPK counter is supposed to be a line, and counter is where the words are supposed to be saved
finalPressedKey[FPKcounter][counter] =
finalPressedKey[FPKcounter] + PressedKey[x + counter];
System.out.println(Arrays.toString(finalPressedKey));
}
}
Whenever I Press a Button, it should be saved in my PressedKey Array, and finalPressedKey is supposed to contain itself, and PressedKey (also , only the last element of the array is supposed to be printed), but instead it just prints [[Ljava.lang.String;#76f42c4b]
I also tried using Arrays.deepToString(); but it gives me the same output as with Arrays.toString();
Thanks for your help!
A String[][] is not a 2-d array. It is an array of String[]. The difference is subtle but important.
The method Arrays.toString() takes an array, iterates through its elements, calls toString() on all of them, and adds a prefix, suffix, and delimiters. Since you give it a String[][] (an array of String[]), it will do the following:
Iterate through the elements (each of them a String[])
call toString() on each element - giving the default toString() value of an array - i.e. its memory address (not really but for this purpose it doesn't matter)
concatenate
Luckily for you, there is an easier way - just use Arrays.deepToString(). This behaves as you would expect.
I did not understand the whole code, but following statement is very suspicious:
finalPressedKey[FPKcounter][counter] =
finalPressedKey[FPKcounter] + PressedKey[x + counter];
since it is adding an array (finalPressedKey[...]) to a string (PressedKey[...]), which will result in that strange text - the standard textual representation of an array (returned by toString). (from a mathematical point of view, it's strange to have 2 indexes )2D_ before the assignment and only one on the right side (1D) for same matrix)
I'm not sure, since we cannot see what counteris, but I believe you wanted something like:
finalPressedKey[FPKcounter][counter] =
finalPressedKey[FPKcounter][counter] + PressedKey[x + counter];
that is, an additional [counter] on second line.
This can also be written as
finalPressedKey[FPKcounter][counter] += PressedKey[x + counter];
If you only want to store lines of strings, a normal String[] is good for you
finalPressedKey[FPKcounter] += PressedKey[x + counter];
even though I wouldn't recomment doing this, no matter what you're trying to accomplish, since this will create a new String object each time a key is pressed.
Maybe ask the question differently and tell us what you're trying to do. I guess String arrays might not be the way to go.
You have to print the elements of your array with
for(int i = 0; i<finalPressedKey[0].length; i++){
for(int j=0; j<finalPressedKey[1].length; j++){
System.out.println(finalPressedKey[i][j]);
}
}
if I understand it correctly.

Read an element of an array whilst containing various data

I am currently seeking for a bit of help with the use of arrays. Quite a newbie on the Java language, so excuse the poor etiquette towards the programming format and I forwardly thank for any answers provided.
My current quarrel with the Array is how to fetch data from any array element. Currently I use the method System.out.println(Arrays.toString(listarray)) but the problem with this method is that it's not necessarily User friendly and it can't be formatted (to my little knowledge). So I'd like to ask help on how to fetch data from an element of an array and put it in a way so its readable by any given user.
Here is the code I'm utilizing:
import java.util.Arrays;
import java.util.Scanner;
public class principal {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Array Example");
String[] listarray = new String[10];
int i = 0;
byte op;
do {
System.out.println("Select your option:");
System.out.println("1-Add");
System.out.println("2-Check");
System.out.println("3-Change");
op = input.nextByte();
switch (op) {
case 1:
input.nextLine();
System.out.println("First String:");
String a1 = input.nextLine();
System.out.println("Second String:");
String a2 = input.nextLine();
System.out.println("Third String:");
String a3 = input.nextLine();
System.out.println("(" + (i + 1) + "/10)");
listarray[i] = a1 + a2 + a3;
i++;
break;
case 2:
System.out.println(Arrays.toString(listarray));
break;
}
}while(op != 9);
}
}
While the code does work, I'd like to know how to format the data, and from a single element, not every element. Or even if I can. Thanks and I appreciate the time spent reading this question.
You have two questions:
How do you reference an array element?
How do you format output?
When you declare an array like
String[10] names;
You have an array that can hold 10 strings, numbered 0 to 9. To reference the fifth element (remembering that array indices start at 0), you would use
names[4]
You can do various things with a reference. If you put it on the right side of an equals sign, then you are assigning the value at that element to something else.
currentName = names[4];
If you put it on the left side, you are assigning something to that element.
names[4] = "Michael";
And if you put it in a println statement, it will output the value to wherever the println statement is putting things at that time, usually the console:
System.out.println(names[4]);
So much for references. And, incidentally, that's what it is called -- you are referencing the 5th element of the array, or you are referencing the indicated element of the array. You can also put the number in a variable:
var i = 4;
System.out.println[i];
Note that most of these uses of the reference assume there is something IN that element of the array. Until something is assigned there, the element is a null.
To format, I recommend looking (carefully) into the Format / Formatter classes and choosing some simple things to do what you want. As an example, you could have:
String formatString = "The name is currently %s.";
String outputString = String.format(formatString, names[i]);
and String's format method will substitute whatever is in names[i] for the %s in the format. There are also formats for ints, doubles, and dates.
For more info, see the Oracle Tutorial on arrays and on manipulating Strings.
Hope that helps
If you want to traverse the Array that is how you can do it:-
for(int i = 0; i < listArray.length; i++) {
System.out.println(listArray[i]);
}
or
for (String s : listArray) {
System.out.println(s);
}

Having problems with a search method between Arrays and Array lists

OK so I'm trying to design a simple program that checks to see if a substring of length 4 characters is within all initial strings. Here is my code as follows:
public class StringSearch{
private String[] s1Array = {"A","C","T","G","A","C","G","C","A","G"};
private String[] s2Array = {"T","C","A","C","A","A","C","G","G","G"};
private String[] s3Array = {"G","A","G","T","C","C","A","G","T","T"};
//{for (int i = 0; i < s1Array.length; i++){
// System.out.print(s1Array[i]);
//}}//check if Array loaded correctly
/**
* This is the search method.
*
* #param length length of sub string to search
* #param count counter for search engine
* #param i for-loop counter
* #return subStr returns strings of length = 4 that are found in all 3 input strings with at most
* one mismatched position.
*/
public String Search()
{
int length = 4;
int count = 0;
int i = 0;
ArrayList<StringSearch> subStr = new ArrayList<StringSearch>();
//String[] subStr = new String[4];
do
{
for (i = count; i < length; i++){
subStr.add(s1Array[i]); // cant find .add method???
count = count + 1;
}
if (s2Array.contains(subStr) && s3Array.contains(subStr)){ //can't find .contains method???
System.out.println(subStr + "is in all 3 lists.");
}
if (count = s1Array.length){
System.out.println("Task complete.");
}
else{
count = count - length;
count = count + 1;
}
}while (count <= s1Array.length);
}
}
For some reason, Java cannot seem to find the .add or .contains methods and I have no idea why. So my approach was to turn the initial Strings each into an array (since the assignment specified each string would be exactly N elements long, in this case N = 10) where 1 letter would be 1 element. The next thing I did was set up a for loop that would scan s1Array and add the first 4 elements to an ArrayList subStr which is used to search s2Array and s3Array. Here is where .add isn't a valid method, for whatever reason. Commenting that out and compiling again, I also ran into an issue with the .contains method not being a valid method. Why won't this work? What am I missing? Logically, it seems to make sense but I guess maybe I'm missing something in the syntax? Help would be appreciated, as I'm a Java novice.
There are lots of errors and misunderstandings here.
Let's start with #1
private String[] s1Array = {"A","C","T","G","A","C","G","C","A","G"};
Making an array of strings is just silly, you should either use a single string or an array of characters.
private String s1 = "ACTGACGCAG";
Or
private char[] s1Array = {'A','C','T','G','A','C','G','C','A','G'};
Now #2
ArrayList<StringSearch> subStr = new ArrayList<StringSearch>();
This means you are trying to make an ArrayList that contains objects of type StringSearch. StringSearch is a class that contains your three arrays and your Search function so I don't think this is what you want.
If you wanted to make a list of 3 strings you might do something like this:
ArrayList<String> stringList = new ArrayList<String>();
stringList.add(s1);
stringList.add(s2);
stringList.add(s3);
Now say you defined s1, s2 and s3 as strings you can do something like this.
for(int i = 0; i <= s1.length() - 4; i++)
{
String subStr = s1.substring(i, i + 4);
if(s2.contains(subStr) && s3.contains(subStr))
{
System.out.println(subStr + " is in all 3 lists.");
}
}
System.out.println("Task Complete.");
The above code should achieve what it looks like you are trying to do. However, it should be noted that this isn't the most efficient way, just a way, of doing it. You should start with some more basic concepts judging by the code you have so far.
After declaring subStr as ArrayList you can call add or contains only with StringSearch objects as parameters.
Instead of:
ArrayList<StringSearch> subStr = new ArrayList<StringSearch>();
Replace it with:
String subStr = "";
And within the for loop to get the first 4 letters in s1 to be in its own string (subStr) add the line:
subStr += s1Array[i];
Also, s1Array is a String array, and not a String. The .contains method is a method that belongs to String variables, so for eg. the way you have it implemented, you can say s1Array[i].contains. But you cannot say s1Array.contains. If you change your String arrays to Strings and edit your code to suit, everything should work the way you expect it to work.
First of all you need to educate yourself on the concept of Java generics.
The most basic thing about generics is that once you declare a collection, here it is the arraylist, as you can only add objects of StringSearch.
Second of all, logically what you can do is to implement an algorithm called
Longest Common Subsequence. Check in pairs whether the longest subsequeces are 4 or not on the arrays.

How to print several strings backwards in Java

I am trying to take a file full of strings, read it, then print out a few things:
The string
The string backwards AND uppercase
The string length
There are a few more things, however I haven't even gotten to that point and do not want to ask anyone to write the code entirely for me. After messing around with it for a while, I have it almost completed (I believe, save for a few areas).
The piece that is tripping me up is the backwards word. We are required to put our output neatly into columns using prinf, but I cannot do this if I read each char at a time. So I tried setting a String backwardsWord = ""; and adding each character.
This is the piece that is tripping me up:
for(int i = upperCaseWord.length() - 1; i >= 0; i--)
{
backwardsWord += (upperCaseWord.charAt(i) + "");
}
My issue is that when I print it, the first word works properly. However, each word after that is added to the previous word.
For example: if I am printing cat, dog, and rat backwards, it shows
TAC
TACGOD
TACGODTAR
I obviously want it to read
TAC
GOD
TAR
Any help would be appreciated.
It looks like your variable backwardsWord is always appending a character without being reset between words. The simplest fix is to clear the backwardsWord just before your loop by setting it to empty string.
backwardsWord = ""; //Clear any existing characters from backwardsWord
for(int i = upperCaseWord.length() - 1; i >= 0; i--)
{
backwardsWord += (upperCaseWord.charAt(i) + "");
}
If you are building up a String one character at a time you will be using a lot of memory because Java Strings are immutable.
To do this more efficiently use a StringBuilder instead. This is made for building up characters like what you are doing. Once you have finished you can use the toString method to get the String out.
StringBuilder builder = new StringBuilder(); //Creates the String builder for storing the characters
for(int i = upperCaseWord.length() - 1; i >= 0; i--)
{
builder.append(upperCaseWord.charAt(i)); //Append the characters one at a time
}
backwardsWord = builder.toString(); //Store the finished string in your existing variable
This has the added benefit of resetting the backwardsWord each time.
Finally, since your goal is to get the String in reverse we can actually do it without a loop at all as shown in this answer
backwardsWord = new StringBuilder(upperCaseWord).reverse().toString()
This creates a new StringBuilder with the characters from upperCaseWord, reverses the characters then stores the final string in backwardsWord
Where are you declaring the String backwardsWord?
If you don't clear it between words then the memory space allocated to that string will still contain the previously added characters.
Make sure you are tossing in a backwardsWord = ""; in between words to reset it's value and that should fix your problem.
Without seeing more of your code I can't tell you exactly where to put it.
This should do the job ->
class ReverseWordsInString{
public static String reverse(String s1){
int l = s1.length();
if (l>1)
return(s1.substring(l-1) + reverse(s1.substring(0,l-1)));
else
return(s1.substring(0));
}
public static void main(String[] args){
String st = "Cat Dog Rat";
String r = "";
for (String word : st.split(" "))
r += " "+ reverse(word.toUpperCase());
System.out.println("Reversed words in the given string: "+r.trim());
}
}

Java Enhanced For Loop - Editing Original Array Values

I'd like to know, in detail, how the Enhanced For Loop works in Java (assuming i do get how the basic usage of this loop is and how it works in general).
Given the following code:
String[] a = {"dog", "cat", "turtle"};
for (String s : a) {
out.println("String: " + s);
s = in.readLine("New String? ");
}
It doesn't actually modify the original list 'a'.
Why not? How memory Management works? Isn't 's' a reference to the same memory cell of 'a[i]'?
I read on the oracle documentation that enhanced for loops can't be used to remove elements from the original array, it makes sense. Is it the same for modifying values?
Thanks in advance
Isn't 's' a reference to the same memory cell of 'a[i]'?
Originally, yes. But then in.readLine produces a reference to a new String object, which you then use to overwrite s. But only s is overwritten, not the underlying string, nor the reference in the array.
s is a local variable that points to the String instance. It is not associated with a[i], they just happen to have the same value initially.
You can only write
for (int i = 0; i < a.length; i++) {
out.println("String: " + a[i]);
a[i] = in.readLine("New String? ");
}
You can't use for-each loops to modify the original collection or array.
Think in s like an address to an object. The thing here is that s is pointing out to a certain value of the array when using the for loop. When you reassing s inside the loop is just happen that s points out to another value but the original value of the array is not modified as you are only changing the address s is pointing to.
String[] a = {"dog", "cat", "turtle"};
for (String s : a) {
//s --> "dog"
out.println("String: " + s);
s = in.readLine("New String? ");
//s --> the new string the user inputs
}
For every iteration String s initially references to corresponding String object in String a[]. But it is then referenced to another String object that is returned by in.readLine().

Categories

Resources