I am trying to sort an array of Strings using compareTo()
. This is my code:
static String Array[] = {" Hello ", " This ", "is ", "Sorting ", "Example"};
String temp;
public static void main(String[] args)
{
for (int j=0; j<Array.length;j++)
{
for (int i=j+1 ; i<Array.length; i++)
{
if (Array[i].compareTo(Array[j])<0)
{
String temp = Array[j];
Array[j] = Array[i];
Array[i] = temp;
}
}
System.out.print(Array[j]);
}
}
Now the output is:
Hello This Example Sorting is
I am getting results, but not the results I want to get, which are:
Hello This Example Is Sorting
How can I adjust my code to sort the string array properly?
Apart from the alternative solutions that were posted here (which are correct), no one has actually answered your question by addressing what was wrong with your code.
It seems as though you were trying to implement a selection sort algorithm. I will not go into the details of how sorting works here, but I have included a few links for your reference =)
Your code was syntactically correct, but logically wrong. You were partially sorting your strings by only comparing each string with the strings that came after it. Here is a corrected version (I retained as much of your original code to illustrate what was "wrong" with it):
static String Array[]={" Hello " , " This " , "is ", "Sorting ", "Example"};
String temp;
//Keeps track of the smallest string's index
int shortestStringIndex;
public static void main(String[] args)
{
//I reduced the upper bound from Array.length to (Array.length - 1)
for(int j=0; j < Array.length - 1;j++)
{
shortestStringIndex = j;
for (int i=j+1 ; i<Array.length; i++)
{
//We keep track of the index to the smallest string
if(Array[i].trim().compareTo(Array[shortestStringIndex].trim())<0)
{
shortestStringIndex = i;
}
}
//We only swap with the smallest string
if(shortestStringIndex != j)
{
String temp = Array[j];
Array[j] = Array[shortestStringIndex];
Array[shortestStringIndex] = temp;
}
}
}
Further Reading
The problem with this approach is that its asymptotic complexity is O(n^2). In simplified words, it gets very slow as the size of the array grows (approaches infinity). You may want to read about better ways to sort data, such as quicksort.
To begin with, your problem is that you use the method `compareTo() which is case sensitive. That means that the Capital letters are sorted apart from the lower case. The reason is that it translated in Unicode where the capital letters are presented with numbers which are less than the presented number of lower case. Thus you should use `compareToIgnoreCase()` as many also mentioned in previous posts.
This is my full example approach of how you can do it effecively
After you create an object of the Comparator you can pass it in this version of `sort()` which defined in java.util.Arrays.
static<T>void sort(T[]array,Comparator<?super T>comp)
take a close look at super. This makes sure that the array which is passed into is combatible with the type of comparator.
The magic part of this way is that you can easily sort the array of strings in Reverse order you can easily do by:
return strB.compareToIgnoreCase(strA);
import java.util.Comparator;
public class IgnoreCaseComp implements Comparator<String> {
@Override
public int compare(String strA, String strB) {
return strA.compareToIgnoreCase(strB);
}
}
import java.util.Arrays;
public class IgnoreCaseSort {
public static void main(String[] args) {
String strs[] = {" Hello ", " This ", "is ", "Sorting ", "Example"};
System.out.print("Initial order: ");
for (String s : strs) {
System.out.print(s + " ");
}
System.out.println("\n");
IgnoreCaseComp icc = new IgnoreCaseComp();
Arrays.sort(strs, icc);
System.out.print("Case-insesitive sorted order: ");
for (String s : strs) {
System.out.print(s + " ");
}
System.out.println("\n");
Arrays.sort(strs);
System.out.print("Default, case-sensitive sorted order: ");
for (String s : strs) {
System.out.print(s + " ");
}
System.out.println("\n");
}
}
run:
Initial order: Hello This is Sorting Example
Case-insesitive sorted order: Hello This Example is Sorting
Default, case-sensitive sorted order: Hello This Example Sorting is
BUILD SUCCESSFUL (total time: 0 seconds)
The method compareToIgnoreCase()
, although it works well with many occasions(just like compare string in english),it will wont work well with all languages and locations. This automatically makes it an unfit choice for use. To make sure that it will be suppoorted everywhere you should use compare()
from java.text.Collator.
You can find a collator for your location by calling the method getInstance()
. After that you should set this Collator's strength property. This can be done with the setStrength()
method together with Collator.PRIMARY
as parameter. With this alternative choise the IgnocaseComp can be written just like below. This version of code will generate the same output independently of the location
import java.text.Collator;
import java.util.Comparator;
//this comparator uses one Collator to determine
//the right sort usage with no sensitive type
//of the 2 given strings
public class IgnoreCaseComp implements Comparator<String> {
Collator col;
IgnoreCaseComp() {
//default locale
col = Collator.getInstance();
//this will consider only PRIMARY difference ("a" vs "b")
col.setStrength(Collator.PRIMARY);
}
@Override
public int compare(String strA, String strB) {
return col.compare(strA, strB);
}
}
If you use:
if (Array[i].compareToIgnoreCase(Array[j]) < 0)
you will get:
Example Hello is Sorting This
which I think is the output you were looking for.
Starting from Java 8, you can also use parallelSort
which is useful if you have arrays containing a lot of elements.
Example:
public static void main(String[] args) {
String[] strings = { "x", "a", "c", "b", "y" };
Arrays.parallelSort(strings);
System.out.println(Arrays.toString(strings)); // [a, b, c, x, y]
}
If you want to ignore the case, you can use:
public static void main(String[] args) {
String[] strings = { "x", "a", "c", "B", "y" };
Arrays.parallelSort(strings, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.compareToIgnoreCase(o2);
}
});
System.out.println(Arrays.toString(strings)); // [a, B, c, x, y]
}
otherwise B
will be before a
.
If you want to ignore the trailing spaces during the comparison, you can use trim()
:
public static void main(String[] args) {
String[] strings = { "x", " a", "c ", " b", "y" };
Arrays.parallelSort(strings, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.trim().compareTo(o2.trim());
}
});
System.out.println(Arrays.toString(strings)); // [ a, b, c , x, y]
}
See:
I know this is a late reply but maybe it can help someone.
Removing whitespace can be done by using the trim() function. After that if you want to sort the array with case sensitive manner you can just use:
Arrays.sort(yourArray);
and for case insensitive manner:
Arrays.sort(yourArray,String.CASE_INSENSITIVE_ORDER);
Hope this helps!
Instead of this line
if(Array[i].compareTo(Array[j])<0)
use this line
if(Array[i].trim().compareTo(Array[j].trim())<0)
and you are good to go. The reason your current code is not working is explained by other users already. This above replacement is one workaround amongst several that you could apply.
" Hello " , " This " , "is ", "Sorting ", "Example"
First of all you provided spaces in " Hello "
and " This "
, spaces have a lower value than alphabetic characters in Unicode, so it gets printed first. (The rest of the characters were sorted alphabetically).
Now upper case letters have a lower value than lower case letter in Unicode, so "Example" and "Sorting" gets printed, then at last "is "
which has the highest value.
Source: Stackoverflow.com