如何按字母顺序排序String数组(不使用compareTo或Arrays.sort)

我需要按字母顺序组织一个字符串数组。 从理论上讲,每个单词的第一个字母都是大写的(尽管不一定,因为人们不能总是信任用户)。 我试过Arrays.sort() ,它不会运行程序。 我尝试过使用compareTo() ,当它运行程序时,当它到达那段代码时,我收到此错误:

 Exception in thread "main" java.lang.NullPointerException at java.lang.String.compareTo(Unknown Source) at NameandAge.printNameOrder(NameandAge.java:431) at NameandAge.print(NameandAge.java:350) at NameandAge.main(NameandAge.java:116) 

从字面上看,我在这个问题上找到的一切都给了我这两个解决方案中的一个。 还有其他建议吗?

(对于记录,代码当前读取:)

 while(!done) { done=true; for(int i=0;i0) { temp=organizedNames[i]; //temp is a String that was declared earlier organizedNames[i]=organizedNames[i+1]; organizedNames[i+1]=temp; done=false } } } } } 

编辑:尝试检查以确保name1和name2不为null 。 它现在有效,但这是输出:乔
法案
短发
工匠
罗德尼
詹姆士
菲利普
莉莲
查理
天使
颂歌
诺亚
我现在添加了整段代码(当然,减去while循环)。 这基本上是我找到的确切解决方案,也是第一个给我任何输出的解决方案。 我究竟做错了什么?

编辑(再次):这是调用排序的代码。

 String[]organizedNames=new String[names.length]; organizedNames=sortNames(organizedNames); 

排序本身的代码基本上就是下面的答案。

假设您正在运行冒泡排序算法的某些变体,并且您尚未清理输入数组的空字符串,则问题很可能是organizedNames[i]为空。

如果是这种情况,您需要决定是否要删除空项,或者在数组末尾列出它们。 如果后者为真,则在进行比较之前,检查name1 == null || name2 == null name1 == null || name2 == null如果是这样,将num设置为-1,这会将所有null项放在一个数组中。

要回答您的次要问题,请尝试以下方法:

 boolean done = false; while(done == false){ done = true; for(int i=0;i0) { String temp=organizedNames[i]; organizedNames[i]=organizedNames[i+1]; organizedNames[i+1]=temp; done=false; } } } 

你已经把自己搞得一团糟了! 你一直在尝试做的是从头开始实现你自己的排序算法,而不理解为什么原始版本不起作用。 它没有用……出于同样的原因原始版本不起作用。

如果我正确读取证据,则问题的根本原因是输入数组中的null值。 有三种简单的方法可以解决这个问题:

  1. 通过创建一个消除了null值的新(较小)数组来摆脱null值。

  2. null值替换为可以安全地比较而不会导致NPE的某个值(例如,空String )。

  3. 实现一个容忍nullComparator 。 例如,如果我们想在非空字符串之后进行null排序…

      public class MyComparator implements Comparator { public int compare(String s1, String s2) { if (s1 == null) { return (s2 == null) ? 0 : +1; } else { return (s2 == null) ? -1 : s1.compareTo(s2); } } } String[] array = ... Arrays.sort(array, new MyComparator()); 

如果您对问题中的代码没有正确排序感兴趣,那是因为您处理null策略。 基本上,代码(如编写的)比较连续的数组条目对,如果它们乱序则交换它们。 当它通过没有找到任何东西的数组进行交换时,它就会停止。 问题是如果它所比较的​​任何一个元素都是null ,那么它就不会比较它们。 因此,如果数组中有null ,则null之前的任何非null元素都不能与null之后的任何非null元素进行比较。

使用集合我们可以这样做..

 SortedSet set = new TreeSet(); String[] s = { "this", "will", "be", "sorted", "without", "ba", "any", "sort()", "function", "or","comparator" }; for (int i = 0; i < s.length; i++) { set.add(s[i]); } for (Object element : set) { System.out.println(element.toString()); } 

首先,String类是不可变的,即无论你如何排序或排列它。 它永远不会改变自身内部的插入顺序。

这是因为当您创建String类对象时,将在String Constant / Literal Pool中分配一个内存,该内存可能被同时在同一JRE上运行的许多其他程序/方法使用。

  class Test{ public static void main(String args[]){ String s="Jake"; s.concat(" Paul");//concat() method appends the string at the end System.out.println(s);//will print Jake because strings are immutable objects } } 

因此,尝试通常的排序算法不会在这里工作。

您可以如何使用StringBuilder而不是String。 由于StringBuilder是可变的,因此您的手动排序算法应该适用于它们。

希望这可以帮助。

使用此代码不使用任何预定义的 Array.Sort()compareTo() 方法

 sortStringArray(new String[]{"Henry Bernard", "Cherish Davidson", "Joshua Norris", "Eleanor Kelley", "Jaslyn Schneider", "Holly Herman", "Willie Strong", "Eliana Villa", "Lennon Odom", "Monica Velasquez", "Salvatore Levy", "Taliyah Bruce"}); public static void sortStringArray(String[] array) { for (int i = 0; i <= array.length - 1; i++) { for (int j = 1; j < array.length - i; j++) { //Apply the bubble Sort if (CompareString(array[j - 1], array[j]) == 1) { //Pass the two adjacent string for comparing String temp = array[j - 1]; array[j - 1] = array[j]; array[j] = temp; } } } for (int i = 0; i <= array.length - 1; i++) { System.out.println(array[i]); } } private static int CompareString(String first, String second) { int len; if (first.length() >= second.length()) //we need to take the smallest string length len = second.length(); else len = first.length(); for (int i = 0; i <= len; i++) { if (first.charAt(i) > second.charAt(i)) //Suppose the first string letters is greater then return 1; return 1; else if (first.charAt(i) < second.charAt(i)) //if second string letter is greater then return -1; return -1; } return 0; //if both the equal then return 0 }