Taking in a File and Alphabetizing it in Java: NullPointer Exception [duplicate] - java

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 6 years ago.
I am trying to read in a file and alphabetize the names. The file has a list of first and last names, for example:
Bob Flower
Tina Sea
Krusty Crab
Mark Klutz
I want to use bubble sort to alphabetize the strings. I keep getting an error saying:
java.lang.NullPointerException
at java.lang.String.compareTo(Unknown Source)
at BubbleSort.Alphabetize(BubbleSort.java:48)
at BubbleSort.main(BubbleSort.java:31)
My Code so far is:
import java.util.*;
import java.io.*;
public class BubbleSort
{
public static void main(String[] args)
throws IOException
{
File inData = new File("names.txt");
if (!inData.exists()) {
System.out.println("File does not exist");
System.exit(0);
}
Scanner input = new Scanner(inData);
int x = 0;
String[] name = new String[30];
//String[] extra = new String[30];
while (input.hasNext()) {
name[x] = input.next();
input.nextLine();
// extra[x] = input.next();
// System.out.println(name[x]);
x++;
}
BubbleSort sorter = new BubbleSort();
sorter.Alphabetize(name, x);
for (int i = 0; i < x; i++) {
System.out.println(name[i]);
}
input.close();
}
private static void Alphabetize(String[] array, int a)
throws IOException
{
String temp;
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length - 1 - i; j++) {
if (array[j].compareTo(array[j + 1]) > 0) {
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
}
}
I don't understand how to fix this error, or what is truly wrong.

You're sorting an unused (and therefore null) array element. Instead of array.length you should be using a, throughout the sort method. That's what a is for.

I guess String[] name = new String[30]; contains null elements. In your example there are only 8 strings
Bob Flower
Tina Sea
Krusty Crab
Mark Klutz
However you create an array with 30 elements. As result there will be 8 String objects in the array and 22 null.
And later on in array[j].compareTo(array[j + 1]) there is comparison between a valid String object and null. Try to use ArrayList instead of String[].

You have problem with allocating memory(array) and using calculated indeces to access element. As a result you have a problem accessing not initialized elements or another time you could get IndexOutOfBoundExceptions. As a beginner it might helpful to learn and do it in low level, but I would like to share a little for your interest, and also it may help not to hate Java.
File class is old, try to use NIO.2 which came with Java 7.
For higher level abstraction here is a one line sorting solution:
Files.readAllLines(Paths.get("names.txt"))
.stream().filter(p -> p.length() > 0)
.forEachOrdered(System.out::println);
It could be even tried out in JShell(Java 9).
Files.readAllLines(Paths.get("names.txt"))
.stream().filter(p -> p.length() > 0)
.sorted()
.toArray(String[]::new);
Output:
{ "Bob Flower", "Krusty Crab", "Mark Klutz", "Tina Sea" }

Nope - You're accessing a null array element past the size of your array length. When you're at the end and access array[j + 1], it's null.
if (array[j].compareTo(array[j + 1]) > 0) { <- culprit here

Related

Accessing index values before and after symbol from input

I am trying to take the input and if there is an # symbol in the input then it finds the maximum of the integers before and after the # symbol. The maximum part I have no problem with but I do not know how to access and find the values before and after the # symbol.
import java.util.Scanner;
public class Max_Min {
public static void main(String[] args) {
//gets keyboard
Scanner keyboard = new Scanner(System.in);
//puts input into string
String inputString = keyboard.nextLine();
//splits string between characters
String[] splitInput = inputString.split("");
for (String s : splitInput) {
if(s.equals("#")){
//computes the maximum of the two integers before and after the #
}
}
//close keyboard
keyboard.close();
I did do a search to find something simliar (and im sure there is something) but could not find anything. If someone could help that would be great!
Try with this:
for (int i = 0; i < splitInput.length; i++){
if (splitInput[i].equals("#") && i != 0 && i != splitInput.length -1){
int max = Math.max(Integer.parseInt(splitInput[i - 1]), Integer.parseInt(splitInput[i + 1]));
}
//...
}
You could try:
String[] splitInput = inputString.split("#");
which would split your string at the #s.
Then you can do a iteration over your splitInput array and do a .length on each index.
You have written the simple for loop, with which you can only access the string, but not its index in the array. If you had the index, you could write:
int possibleMax = Integer.parseInt(splitInput[i - 1]) + Integer.parseInt(splitInput[i + 1]);
To get the index, there are two ways:
for (int i = 0; i < splitInput.length; i++) {
String s = splitInput[i];
...
}
Or:
int i = 0;
for (String s : splitInput) {
…
i++;
}
I don't like either version because both are more complicated than absolutely necessary, in terms of written code. If you would use Kotlin instead of Java, it would be:
splitInput.forEachIndexed { i, s ->
…
}
In Java this could be written:
forEachIndexed(
splitInput,
(i, s) -> …
);
The problem in Java is that the code inside the … cannot update the variables of the enclosing method. I'm not sure whether this will ever change. It would be possible but needs a lot of work by the language committee.
A simple way to do this would be
String input = "12#23";
String [] arr = input.split("#");
if (arr.length == 2) {
System.out.println("Max is "+Math.max(Integer.valueOf(arr[0]),Integer.valueOf(arr[1])));
}

Array turns up full of nulls after I filled it using for loop [duplicate]

This question already has answers here:
Getting ArrayIndexOutOfBoundsException Exceptions [duplicate]
(5 answers)
Closed 4 years ago.
Hello I am building a Java program that takes in a file called wordlist which contains all of the words in the dictionary, one per line, and I pass it in through a scanner so that later I can use algorithms to search through it:
File file = new File("wordlist.txt");
Scanner scanner = new Scanner(file);
String [] words = new String[69903];
No problem here. Then I try to populate the words array using a for loop:
for(int i = 0; scanner.hasNextLine(); i++) {
String input = scanner.nextLine();
words[i] = input;
}
This is where the problem is. I tried printing input every iteration of the loop and its an actual word from the .txt file. I also tried printing words[i] during the loop for each iteration and it also worked. Yet somehow when I iterate through the array after the loop it is full of nulls which obviously creates problems for the program down the line. What is happening and how can I fix it. Thank you.
By the way here is the entire program:
import java.util.Scanner;
import java.util.Arrays;
import java.io.File;
public class BinarySearch {
public static void main(String[] args) throws Exception {
File file = new File("wordlist.txt");
Scanner scanner = new Scanner(file);
String [] words = new String[69903];
// Something here not working
for(int i = 0; scanner.hasNextLine(); i++) {
String input = scanner.nextLine();
words[i] = input;
}
System.out.println("Done reading input words");
System.out.println("Done sorting input words");
Scanner query = new Scanner(System.in);
String key = query.nextLine();
if(search(key, words, 0, words.length) < 0) {
System.out.println(key + " is not in the english dictionary.");
} else {
System.out.println(key + " is part of the english dictionary.");
}
}
public static int search(String key, String[] arr, int lo, int
hi) {
if(hi <= lo) {
return -1;
}
int mid = lo + (hi - lo) / 2;
int compute = arr[mid].compareTo(key);
if (compute > 0) {
return search(key, arr, lo, mid);
}
if (compute < 0) {
return search(key, arr, mid + 1, hi);
}
else {
return mid;
}
}
}
This is the error I get:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 69903
at BinarySearch.main(BinarySearch.java:19)
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 69903 at BinarySearch.main(BinarySearch.java:19)
Do you have more than 69903 lines in the file or one extra empty line?
if(search(key, words, 0, words.length) < 0)
Try to put 'i' instead of 'words.length'. Otherwise you'll process all the array including nulls after your last word.
It will only work if your file contains exactly 69903 lines.

Is it correct to convert 2D CharArray to String and use .charAt() to compare a character?

So I have a char variable called "temp" which I'd like to compare to the element stored in "X" CharArray[X][Y] while I'm in a third for loop after the 2D array.
For example:
char temp;
temp = ' ';
String end;
end = "";
for (int i = 0; i < CharArray.length; i++){
for (int m = 0; m < 2; m++){
if (somethingY){
if (somethingZ){
for (int j = 0; j < something.length; j++){
//something
temp = somethingX;
if (temp == String.valueOf(CharArray[i][m]).charAt(0)){
end = String.valueOf(CharArray[i][m]);
System.out.print(end);
}
}
}
}
}
}
I've tried printing "temp" where it says "temp = somethingX" and it prints just fine. But when I try to save the String into a String variable, it will not print the variable called "end".
According to this, it won't do anything if the object is something else, but "end" is a String.
So, what am I doing wrong?
EDIT: In case there's a confusion, "I'm trying to print "end", but I figured if temp == String.valueOf(CharArray[i][m]).charAt(0) is correct, so should "end"'s part.".
EDIT2: Defined "temp" for people...
EDIT3: I tried "end.equals(String.valueOf(CharArray[i][m]));", but still nothing happens when I try to print it. I get no errors nor anything.
EDIT4: I tried putting String.valueOf(CharArray[i][m]).charAt(0) into a another variable called "temp2" and doing if (temp == temp2), but still the same thing.
EDIT5: I tried temp == CharArray[0][m] and then end = CharArray[0][m], but still nothing prints.
EDIT6: OK. Sense this will never get resolved, I'll just say the whole point of my problem. -> I have an ArrayList where each line is a combination of a letter, space and a number (e.g. "E 3"). I need to check if a letter is repeating and if it is, I need to sum the numbers from all repeating letters.
For example, if I have the following ArrayList:
Z 3
O 9
I 1
J 7
Z 7
K 2
O 2
I 8
K 8
J 1
I need the output to be:
Z 10
O 11
I 9
J 8
K 10
I didn't want people to do the whole thing for me, but it seems I've no choice, since I've wasted 2 days on this problem and I'm running out of time.
Use a map :
ArrayList<String> input=new ArrayList<String>();
input.add("O 2");
input.add("O 2");
Map<String, Integer> map= new HashMap<String, Integer>();
for (String s:input) {
String[] splitted=s.split(" ");
String letter=splitted[0];
Integer number=Integer.parseInt(splitted[1]);
Integer num=map.get(letter);
if (num==null) {
map.put(letter,number);
}
else {
map.put(letter,number+num);
}
}
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + " " + Integer.toString(entry.getValue()));
}
Without using a map :
ArrayList<String> input=new ArrayList<String>();
input.add("O 2");
input.add("O 2");
ArrayList<String> letters=new ArrayList<String>();
ArrayList<Integer> numbers=new ArrayList<Integer>();
for (String s:input) {
String[] splitted=s.split(" ");
String letter=splitted[0];
Integer number=Integer.parseInt(splitted[1]);
int index=-1;
boolean isthere=false;
for (String l:letters) {
index++;
if (l.equals(letter)) {
isthere=true; //BUGFIX
break;
}
}
if (isthere==false) { //BUGFIX
letters.add(letter);
numbers.add(number);
}
else {
numbers.set(index,numbers.get(index)+number);
}
}
for (int i=0; i < letters.size(); i++) {
System.out.println(letters.get(i));
System.out.print(numbers.get(i));
}
Converting it back to have a nice output :
ArrayList<String> output=new ArrayList<String>();
for (int i=0; i < letters.size(); i++) {
output.add(letters.get(i)+" "+Integer.toString(numbers.get(i));
}
Feel free to comment if you are having any questions.

Selection Sort and Bubble Sort Errors [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 6 years ago.
Currently having difficulty with Selection Sort and Bubble Sort codes.
The selection sort is used to sort out student ID in ascending order and the bubble sort is used to sort out last names in ascending order. The program compiles but crashes upon choosing choice 10 or 11.
My array is declared as follows:
student[] list = new student[100]; //my array
This is the code that I have for selection sort and bubble sort. I am using an array with methods:
if (choice == 10) { // Dissplay the sorted array by student id
SortArrayBySelection(list);
System.out.println("Sorted studentid are:");
for (int i =0; i< studentNumber; i++)
{
System.out.println(list[i]);
}
}
if (choice == 11){ // Display the sorted array by family name
BubbleSort(list);
System.out.println("The sorted names are:");
for(int i = 0; i < studentNumber; i++)
{
System.out.println(list[i].Getfamilyname());
}
}
} while (choice != 1);
}
public static void SortArrayBySelection(student[] arrayToSort){ // Function to sort out the array on sutdentid
for(int i = 0; i < arrayToSort.length-1; ++i)
{
int minIndex = i;
int studentid3 = arrayToSort[i].Getstudentid();
int studentid2 = arrayToSort[minIndex].Getstudentid();
for(int j = i + 1; j <arrayToSort.length; ++j)
{
int studentid1 = arrayToSort[j].Getstudentid();
if(studentid1 < studentid2)
{
minIndex = j;
}
}
int temp = studentid3;
studentid3 = studentid2;
studentid2 = temp;
}
}
public static void BubbleSort(student[] arraySort){
String t;
for(int i = 0; i<arraySort.length; i++){
for(int j=0; j<arraySort.length-1;j++){
String str1 = arraySort[j].Getfamilyname();
String str2 = arraySort[j+1].Getfamilyname();
if(str1.compareTo(str2)<0){
t = str1;
str1 = str2;
str2 = t;
}
}
}
}
Any suggestions would be appreciated! thank you
Errors:
Exception in thread "main" java.lang.NullPointerException
at client.Client.SortArrayBySelection(Client.java:270)
at client.Client.main(Client.java:232)
Exception in thread "main" java.lang.NullPointerException
at client.Client.BubbleSort(Client.java:288)
at client.Client.main(Client.java:246)
As you have not mentioned line numbers in your code, also the Student class and the code where you are preparing the student[] list = new student[100]. So, as far as i can see the code from following lines you can get the java.lang.NullPointerException
Your list length will be always 100 as you are creating it with that value. So if it something dynamic values which you are preparing at runtime then it will be better if you use ArrayList<student> list=new ArrayList<student>(); and add the values using list.add(yourObject);.
Exception in thread "main" java.lang.NullPointerException
at client.Client.SortArrayBySelection(Client.java:270)
at client.Client.main(Client.java:232)
For this error you are calling SortArrayBySelection method and the lines which may end up in the above errors are
int studentid3 = arrayToSort[i].Getstudentid();
int studentid2 = arrayToSort[minIndex].Getstudentid();
int studentid1 = arrayToSort[j].Getstudentid();
Reason for the error :
You don't have the values present at the given index and as you are creating an array of length 100 where you put only let say 10-15 values then it will always have no values in other location. But your for-loop will go to 100 index position in which after 10-15 index you will always get null by calling the getters.
Same reason is for your other method as well.

Sorting Strings as inserted into array in Java

I'm trying to create a program that takes user input and sorts it alphabetically as it comes in using compareTo String operations (not array.sort) and prints the final sorted array at the end. I've got most of the body of this problem down but am lost once I get to the sort function. Does anyone have any ideas on how I might be able to finish out the SortInsert method?
import java.util.*;
public class SortAsInserted {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int array_size = GetArraySize();
String[] myArray = new String[array_size];
for (int i = 0; i < array_size; i++){
String nextString = GetNextString();
String[] sortedArray = SortInsert(nextString, myArray);
}
PrintArray(sortedArray);
}
input.close();
}
}
public static String[] SortInsert(String nextString, String[] myArray){
for(int i = 0; i < myArray.length;)
if (nextString.compareToIgnoreCase(myArray[i]) > 0) {
i++;
//if current text is less(alphabetically) than position in Array
}else if (nextString.compareToIgnoreCase(myArray[i]) < 0){
}
}
public static int GetArraySize(){
Scanner input = new Scanner(System.in);
System.out.print("How many items are you entering?: ");
int items_in_array = input.nextInt();
return items_in_array;
}
public static void PrintArray(String[] x) {
for (int i = 0; i < x.length; i++){
System.out.print(x[i]);
}
}
public static String GetNextString(){
Scanner input = new Scanner(System.in);
System.out.println("Enter the next string: ");
String next_string = input.nextLine();
return next_string;
}
}
There are a number of problems with this code. First I'll answer your immediate question, then enumerate some of the other problems.
The SortInsert method takes a String[] that will have been initialized with null values, so you will need to take that into account. The for loop would look something like this. (I'm using comments instead of writing the actual code since I'm not doing the project)
for (int i=0; i<myArray.length; ++i) {
if (myArray[i] == null) {
// we found a blank spot. use it to hold nextString.
break;
} else if (nexString.compareToIgnoreCase(myArray[i]) < 0) {
// nextString should be in spot i, so make room for it
// by shuffling along whatever is in the array at "i" and later
// by one place, then put nextString into position "i"
break;
}
// otherwise we'll just move to the next position to check
}
Now for the other issues.
You have a Scanner object in main that is never used. There's no point in having it and closing it at the end if your other methods make their own.
myArray will always be the sorted array so there's no point in making a local variable called sortedArray and return it from SortInsert. Note that your attempt to print sortedArray would fail anyway because that local variable is only in scope within the for loop.
When printing it should be myArray being passed to PrintArray.
If you're going to sort as you go, the TreeMap data structure is what you should be using, not an array. However, if you want to sort as you go with an array, you need to add some lines into your else if clause in SortInsert (should be sortInsert, BTW). (Another question: why is it else if rather than just else?)
The lines should create a new array of size one greater than the existing array, copy the first i-1 elements of the old array to the new array, put the new element in position i, then copy the remaining elements of the old array into positions one greater in the new array.
Once you find the position you wish to insert at, you have to shift all of the following elements down by one. Something like the following:
String temp = array[position];
for (int j = position+1; j < array_size-1; j++) {
String temp2 = array[j];
array[j] = temp;
temp = temp2;
}
array[array_size-1] = temp;

Categories