Java中的字符串比较

86

"按字典序比较两个字符串"是什么意思?

8个回答

171

根据@Bozho和@aioobe的回答,词典比较类似于字典中的排序。

Java String类提供了.compareTo()方法来进行字符串的词典比较。它的使用方式如下:"apple".compareTo("banana")

方法的返回值是一个int,可以按以下方式解释:

  • 返回<0,则调用该方法的字符串在词典中排名第一(出现在字典的前面)
  • 返回=0,则两个字符串在词典中相等
  • 返回>0,则传递给compareTo方法的参数在词典中排名第一。

更具体地说,该方法提供了ASCII值中第一个非零差异。

因此,"computer".compareTo("comparison")将返回(int) 'u' - (int) 'a'(20)。由于这是一个正数结果,所以参数("comparison")在词典中排名第一。

还有一种变体.compareToIgnoreCase(),例如"a".compareToIgnoreCase("A")将返回0


有关整理比较(例如 'é' 是否等同于 'e'),请查看 http://download.oracle.com/javase/1.5.0/docs/api/java/text/Collator.html。 - Philip
只是一个小问题。"computer".compareTo("comparison")将返回一个值(int) 'u' - (int) 'a' 20,而不是21。 - Coding Bad
字典所使用的语言也很重要,这就是Locale的作用所在。 - Thorbjørn Ravn Andersen

12

"比较"这个词有点误导性。您不是在进行严格意义上的相等比较,而是在比较哪个字符串在字典(词典)中排在前面。

这是一个功能,它使得字符串集合可以进行排序。

请注意,这非常依赖于活动区域设置。例如,在丹麦,我们有一个字符"å",曾经拼写为"aa",它与两个单独的"a"非常不同(编辑:如果发音为"å"!)。因此,丹麦的排序规则将两个连续的"a"与一个"å"视为相同,这意味着它在字母表中排在z之后。这也意味着丹麦语字典的排序方式与英语或瑞典语的排序方式不同。


1
有趣!Java的compareTo方法会考虑这个吗? - aioobe
1
@aioobe,这个Java教程中的解释比我能做得更好:http://download.oracle.com/javase/tutorial/i18n/text/collationintro.html - Thorbjørn Ravn Andersen

10

8

按顺序将位置相同的字母进行比较,就像在字典中排序单词一样。


6
如果您想比较两个字符串在词典中的先后顺序,那么您已经进行了字符串的字典序比较!
一些链接: 从后面的链接中偷来的:

如果一个字符串s在字典序中排在另一个字符串t的前面,则:

  • s是t的前缀;或
  • 如果c和d分别是s和t中第一个不同字符,则在字符顺序中c在d之前。

注:对于字母字符,字符顺序与字母顺序相符。数字排在字母前,大写字母排在小写字母前。

例如:

  • house在household之前
  • Household在house之前
  • composer在computer之前
  • H2O在HOTEL之前

5

Java 字典序排序:

  1. 数字排在 -前面-
  2. 大写字母排在 -前面-
  3. 小写字母

虽然这看起来很奇怪,但它是真实的...
我曾经不得不编写比较器链来改变默认行为。
尝试使用更好的输入字符串示例玩弄以下代码片段以验证顺序(您需要 JSE 8):

import java.util.ArrayList;

public class HelloLambda {

public static void main(String[] args) {
    ArrayList<String> names = new ArrayList<>();
    names.add("Kambiz");
    names.add("kambiz");
    names.add("k1ambiz");
    names.add("1Bmbiza");
    names.add("Samantha");
    names.add("Jakey");
    names.add("Lesley");
    names.add("Hayley");
    names.add("Benjamin");
    names.add("Anthony");

    names.stream().
        filter(e -> e.contains("a")).
        sorted().
        forEach(System.out::println);
}
}

结果

1Bmbiza
Benjamin
Hayley
Jakey
Kambiz
Samantha
k1ambiz
kambiz

请注意,此答案是区域特定的。
请注意,我正在过滤包含小写字母a的名称。


0

你可能会遇到这样一项任务,需要手动实现字典比较,而不使用默认的compareTo()方法。

下面的简单算法基于比较相邻位置上字符的Unicode值。

@Override
public int compareTo(Person otherPerson) {
        
// Getters, constructor, variables ... 

        int result = 0;

            for (int i = 0; i < getName().length() && i < otherPerson.getName().length(); i++) {
                if (getName().charAt(i) > otherPerson.getName().charAt(i)) {
                    result = 1;
                    break;
                } else if (getName().charAt(i) < otherPerson.getName().charAt(i)) {
                    result = -1;
                    break;
                }
            }
        }
        return result;
    }
}

0

以下是算法 "按字典顺序比较两个字符串"

  1. 输入两个字符串string1和string2

  2. for (int i = 0; i < str1.length() && i < str2.length(); i ++)

    (循环遍历两个字符串的每一个字符并进行比较,直到其中一个字符串结束):

    a. 如果两个字符的Unicode值相同,则继续;

    b. 如果string1的字符的Unicode值和string2的字符的Unicode值不同,则返回(str1[i]-str2[i])。

  3. 如果string1的长度小于string2的长度,则

    return str2[str1.length()]

    否则,则

    return str1[str2.length()]

    // 这个方法按字典序比较两个字符串

    public static int compareCustom(String s1, String s2) {
        for (int i = 0; i < s1.length() && i< s2.length(); i++) {
            if(s1.charAt(i) == s2.charAt(i)){
                //System.out.println("Equal");
                continue;
            }
            else{
                return s1.charAt(i) - s2.charAt(i);
            }   
        }
        if(s1.length()<s2.length()){
            return s2.length() - s1.length();
        }
        else if(s1.length()>s2.length()){
            return s1.length()-s2.length();
        }
        else{
            return 0;
        }
    }
    
如果两个字符串相等,它将返回0,否则返回负值或正值。
来源:- 来源

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接