The user is allowed to play with an array of strings. They can add strings to the array, remove strings from the array, search for strings in the array, and eventually they will be able to sort the array. The sorting is what is messing me up. I've tried a few different approaches. The first approach was to convert the array into an ArrayList and use Collections to sort the ArrayList, which would be converted back into the static class array. It doesn't work. The second approach I tried was to iterate through the array and try to sort only the strings added by the user instead of everything in the array (since there are some null values in the array). Perhaps I should iterate through the array and then store the non-null values into a new array that I can then sort? But what if I want to add more strings after sorting the new array? That's why I stopped with the second solution. The third attempt was to use Arrays.sort() on my array but for some reason it does not work.
Here is the exception:
Exception in thread "main" java.lang.NullPointerException
at java.util.ComparableTimSort.countRunAndMakeAscending(ComparableTimSort.java:290)
at java.util.ComparableTimSort.sort(ComparableTimSort.java:157)
at java.util.ComparableTimSort.sort(ComparableTimSort.java:146)
at java.util.Arrays.sort(Arrays.java:472)
at java.util.Collections.sort(Collections.java:155)
at testingSearch.sortArray(testingSearch.java:93)
at testingSearch.main(testingSearch.java:42)
Here is my code:
import java.util.Scanner;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class testingSearch {
static String[] strArray;
static {
strArray = new String[5];
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
while(true){
System.out.println("1. Add string to the string array.");
System.out.println("2. Remove string from the string array.");
System.out.println("3. Display strings in string array.");
System.out.println("4. Search the string array for a string.");
System.out.println("5. Sort the strings in the string array.");
int userChoice = 0;
userChoice = input.nextInt();
switch(userChoice) {
case 1:
addString();
break;
case 2:
removeString();
break;
case 3:
displayStrings();
break;
case 4:
searchArray();
break;
case 5:
sortArray();
break;
}
}
}
public static void addString(){
Scanner input = new Scanner(System.in);
System.out.println("What string do you want to add?");
String userInput;
userInput = input.nextLine();
ArrayList<String> stringList = new ArrayList<String> (Arrays.asList(strArray));
stringList.add(userInput);
strArray = stringList.toArray(strArray);
}
public static void removeString(){
Scanner input = new Scanner(System.in);
System.out.println("What string do you want to remove?");
String userInput;
userInput = input.nextLine();
ArrayList<String> stringList = new ArrayList<String> (Arrays.asList(strArray));
stringList.remove(userInput);
strArray = stringList.toArray(strArray);
}
public static void displayStrings(){
for (String s: strArray){
if (!(s == null)){
System.out.println(s);
}
}
}
public static void searchArray(){
Scanner input = new Scanner(System.in);
System.out.println("What string do you want to search the array for?");
String userInput;
userInput = input.nextLine();
ArrayList<String> stringList = new ArrayList<String>(Arrays.asList(strArray));
if (stringList.contains(userInput)){
System.out.println("The string array contains that string!");
}
else {
System.out.println("The string array does not contain that string...");
}
}
public static void sortArray(){
/*ArrayList<String> stringList = new ArrayList<String> (Arrays.asList(strArray));
Collections.sort(stringList);
strArray = stringList.toArray(strArray);*/
/*for (String s: strArray) {
if (!(s == null)){
Arrays.sort(strArray);
}
}*/
List<String> stringList = new ArrayList<String>(Arrays.asList(strArray));
Collections.sort(stringList);
strArray = stringList.toArray(strArray);
//Arrays.sort(strArray);
}
}
The reason you're getting NullPointerException
s can be explained by the javadoc for Arrays#sort()
(emphasis mine):
Sorts the specified array of objects into ascending order, according to the natural ordering of its elements. All elements in the array must implement the
Comparable
interface.
Because Arrays.sort()
expects Comparable
elements and not null
values, you end up with a NullPointerException
when the method tries to call compareTo()
.
The fix-this-now way of solving this would be to simply make sure all null
elements in your array are replaced with something non- null
, such as ""
. So loop through your array at creation and after removing a String
and set null
elements to ""
. However, this solution probably wouldn't perform too well for your code, as it requires another loop after every String
is removed, which could grow onerous. At least it won't require you to create a bunch of objects, due to the magic of the String
pool, so it's a bit better than what you might do with a different object.
A better solution would be to simply use ArrayList<String>
instead of a raw array; after all, you're already using one to manage addString()
and removeString()
, so you would have less converting from array to ArrayList
and back to do. In addition, you wouldn't need to worry about NPEs when sorting (at least for your use case; adding null
to a Collection
would still result in NPEs when sorting).
You can also just use a raw array, but managing that would get kind of annoying, so I wouldn't recommend that. If you do it right you won't have to worry about NPEs though.
No problem! Here you go:
1. Create a new array
2. Insert items to that array, in the right order
public class sorter {
public static void main(String[] args){
String[] array = new String[]{"HI", "BYE", null, "SUP", ":)"};
//Sort:
String[] newArray = new String[array.length];
int index = 0;
for(int m = 0 ; m < newArray.length; m++){
String leastString = null;
int i = 0;
for(i = 0; i < array.length; i++){
if(leastString==null&&array[i]!=null){
leastString = array[i];
break;
}
}
for(int j = i+1; j < newArray.length; j++){
if(array[j]!=null){
if(array[j].compareTo(array[i])<0){
leastString = array[j];
i = j;
}
}
}
if(i==newArray.length)break;
newArray[m] = leastString;
array[i] = null;
}
for(String s : newArray){
System.out.println(s);
}
}
}
This prints:
:)
BYE
HI
SUP
null
EDIT: Another very simple way to solve this in a very effiecient manner, is to use ArrayList:
public class AClass {
public static void main(String[] args){
String[] array = new String[]{"HI", "BYE", null, "SUP", ":)"};
//Sort:
ArrayList<String> newArray = new ArrayList<String>();
for(String s : array){
if(s!=null){
newArray.add(s);
}
}
Collections.sort(newArray);
String[] retval = new String[newArray.size()];
retval = newArray.toArray(retval);
for(String s : retval){
System.out.println(s);
}
} }
I guess the simple way of doing things really would be:
static String[] strArray;
static {
strArray = new String[5];
for(int i = 0, i < strArray.length; i++)
{
strArray[i] = "";
}
}
And then just call
Arrays.sort(strArray);
When you want to sort it. If that doesn't work, although I think it should; your initial approach would have been the following:
List<String> stringList = new ArrayList<String>();
for(int i = 0; i < strArray.length; i++)
{
stringList.add(strArray[i]);
}
Collections.sort(stringList);
strArray = stringList.toArray(new String[stringList.size()]);
Although it clearly doesn't seem very memory-friendly.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.