`
JavaFans
  • 浏览: 87364 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Java String比较的基础问题

阅读更多
Java6的标准库里面的string比较的方法,感觉其中有部分是多余的。也就是说,两个Byte在比较了Character.toUpperCase(c1)之后,如果不相等,应该这两个char就不一样了,没有必要再比较Character.toLowerCase(c1)了。

public int compare(String s1, String s2) {
            int n1=s1.length(), n2=s2.length();
            for (int i1=0, i2=0; i1<n1 && i2<n2; i1++, i2++) {
                char c1 = s1.charAt(i1);
                char c2 = s2.charAt(i2);
                if (c1 != c2) {
                    c1 = Character.toUpperCase(c1);
                    c2 = Character.toUpperCase(c2);
                    if (c1 != c2) {
                        c1 = Character.toLowerCase(c1);
                        c2 = Character.toLowerCase(c2);
                        if (c1 != c2) {
                            return c1 - c2;
                        }
                    }
                }
            }
            return n1 - n2;
        }


分享到:
评论
7 楼 JavaFans 2010-03-17  
wannago 写道
ivywjhua 写道

char 不仅有字母,还有字符, 如[^
从这个实现来看是用小写字母来做最后比较的

有道理。我gogle了一下,发现了这些:
1. http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6464154
上面说在因为在大写和小写字母间有些字符,如果做ignore case比较,你得做个选择,它们应该大于字母还是小于字母--即基于大写字母比较还是小写字母。
    在windows下,它们都是基于大写字母的,linux是基于小写的。简单测试:建立“aa”,“_a", "[a"文件,然后在windows下dir或者linux下ls比较。
    java和linux下一样都基于小写的。

2. 如果google看看gnu的java实现,可以看到这个函数:
  public int compareToIgnoreCase(String str)
  {
    return this.toUpperCase().toLowerCase().compareTo(
     str.toUpperCase().toLowerCase());
  }

看起来ignore case比较都是先变大写比较,再变小写比较。原因有人给出解释
http://www.codeguru.com/forum/archive/index.php/t-207356.html
上面说:有的字符比如希腊字符sigma有两种不同的小写方式,但是大写方式一样,还有的是大写方式不一样,但小写一样!运行这个测试程序就明白了:
public class T {

    static public void main(String[] args) {
        int CHAR_TEST = 1000;
        for (int i = 0; i < CHAR_TEST; i++) {
            char ch = (char) i;
            for (int j = 0; j < CHAR_TEST; j++) {
                if (i != j) {
                    char ch2 = (char) j;
                    if (ch2 != ch) {
                        boolean b1 = Character.toUpperCase(ch) == Character.toUpperCase(ch2);
                        boolean b2 = Character.toLowerCase(ch) == Character.toLowerCase(ch2);
                        if (b1 && !b2) {
                            System.out.print("UPPER SAME FOR: " + i + " and " + j + ". ");
                            System.out.println("Ch1=" + ch + ". Ch2=" + ch2 + ".");
                        } else if (b2 && !b1) {
                            System.out.print("LOWER SAME FOR: " + i + " and " + j + ". ");
                            System.out.println("Ch1=" + ch + ". Ch2=" + ch2 + ".");
                        }
                    }
                }
            }
        }
    }
}



很有道理,这应该是很全面的回答了。
学到了不少,谢谢
6 楼 wannago 2010-02-21  
ivywjhua 写道

char 不仅有字母,还有字符, 如[^
从这个实现来看是用小写字母来做最后比较的

有道理。我gogle了一下,发现了这些:
1. http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6464154
上面说在因为在大写和小写字母间有些字符,如果做ignore case比较,你得做个选择,它们应该大于字母还是小于字母--即基于大写字母比较还是小写字母。
    在windows下,它们都是基于大写字母的,linux是基于小写的。简单测试:建立“aa”,“_a", "[a"文件,然后在windows下dir或者linux下ls比较。
    java和linux下一样都基于小写的。

2. 如果google看看gnu的java实现,可以看到这个函数:
  public int compareToIgnoreCase(String str)
  {
    return this.toUpperCase().toLowerCase().compareTo(
     str.toUpperCase().toLowerCase());
  }

看起来ignore case比较都是先变大写比较,再变小写比较。原因有人给出解释
http://www.codeguru.com/forum/archive/index.php/t-207356.html
上面说:有的字符比如希腊字符sigma有两种不同的小写方式,但是大写方式一样,还有的是大写方式不一样,但小写一样!运行这个测试程序就明白了:
public class T {

    static public void main(String[] args) {
        int CHAR_TEST = 1000;
        for (int i = 0; i < CHAR_TEST; i++) {
            char ch = (char) i;
            for (int j = 0; j < CHAR_TEST; j++) {
                if (i != j) {
                    char ch2 = (char) j;
                    if (ch2 != ch) {
                        boolean b1 = Character.toUpperCase(ch) == Character.toUpperCase(ch2);
                        boolean b2 = Character.toLowerCase(ch) == Character.toLowerCase(ch2);
                        if (b1 && !b2) {
                            System.out.print("UPPER SAME FOR: " + i + " and " + j + ". ");
                            System.out.println("Ch1=" + ch + ". Ch2=" + ch2 + ".");
                        } else if (b2 && !b1) {
                            System.out.print("LOWER SAME FOR: " + i + " and " + j + ". ");
                            System.out.println("Ch1=" + ch + ". Ch2=" + ch2 + ".");
                        }
                    }
                }
            }
        }
    }
}

5 楼 ivywjhua 2010-02-20  
JavaFans 写道
Java6的标准库里面的string比较的方法,感觉其中有部分是多余的。也就是说,两个Byte在比较了Character.toUpperCase(c1)之后,如果不相等,应该这两个char就不一样了,没有必要再比较Character.toLowerCase(c1)了。

public int compare(String s1, String s2) {
            int n1=s1.length(), n2=s2.length();
            for (int i1=0, i2=0; i1<n1 && i2<n2; i1++, i2++) {
                char c1 = s1.charAt(i1);
                char c2 = s2.charAt(i2);
                if (c1 != c2) {
                    c1 = Character.toUpperCase(c1);
                    c2 = Character.toUpperCase(c2);
                    if (c1 != c2) {
                        c1 = Character.toLowerCase(c1);
                        c2 = Character.toLowerCase(c2);
                        if (c1 != c2) {
                            return c1 - c2;
                        }
                    }
                }
            }
            return n1 - n2;
        }




char 不仅有字母,还有字符, 如[^
从这个实现来看是用小写字母来做最后比较的
4 楼 sing4j 2010-02-20  
asscii
3 楼 JavaFans 2010-02-20  
是这个函数

wannago 写道
String有compare这个方法?莫非你指这个?
    private static class CaseInsensitiveComparator
                         implements Comparator<String>, java.io.Serializable {
	// use serialVersionUID from JDK 1.2.2 for interoperability
	private static final long serialVersionUID = 8575799808933029326L;

        public int compare(String s1, String s2) {
            int n1=s1.length(), n2=s2.length();
            for (int i1=0, i2=0; i1<n1 && i2<n2; i1++, i2++) {
                char c1 = s1.charAt(i1);
                char c2 = s2.charAt(i2);
                if (c1 != c2) {
                    c1 = Character.toUpperCase(c1);
                    c2 = Character.toUpperCase(c2);
                    if (c1 != c2) {
                        c1 = Character.toLowerCase(c1);
                        c2 = Character.toLowerCase(c2);
                        if (c1 != c2) {
                            return c1 - c2;
                        }
                    }
                }
            }
            return n1 - n2;
        }
    }

compare还是得比较哪一个大哪一个小吧

在我的理解,比较大小直接使用c1-c2就行了。
例如一种可能的实现:
    private static class CaseInsensitiveComparator
                         implements Comparator<String>, java.io.Serializable {
	// use serialVersionUID from JDK 1.2.2 for interoperability
	private static final long serialVersionUID = 8575799808933029326L;

        public int compare(String s1, String s2) {
            int n1=s1.length(), n2=s2.length();
            for (int i1=0, i2=0; i1<n1 && i2<n2; i1++, i2++) {
                char c1 = s1.charAt(i1);
                char c2 = s2.charAt(i2);
                if (c1 != c2) {
                    c1 = Character.toUpperCase(c1);
                    c2 = Character.toUpperCase(c2);
                    if (c1 != c2) {
                        //c1 = Character.toLowerCase(c1);
                        //c2 = Character.toLowerCase(c2);
                        //if (c1 != c2) {
                            return c1 - c2;
                        //}
                    }
                }
            }
            return n1 - n2;
        }
    }


2 楼 langhua9527 2010-02-20  
compare还是得比较哪一个大哪一个小吧
=====================================
9494,也把我吓一跳。。。。
1 楼 wannago 2010-02-20  
String有compare这个方法?莫非你指这个?
    private static class CaseInsensitiveComparator
                         implements Comparator<String>, java.io.Serializable {
	// use serialVersionUID from JDK 1.2.2 for interoperability
	private static final long serialVersionUID = 8575799808933029326L;

        public int compare(String s1, String s2) {
            int n1=s1.length(), n2=s2.length();
            for (int i1=0, i2=0; i1<n1 && i2<n2; i1++, i2++) {
                char c1 = s1.charAt(i1);
                char c2 = s2.charAt(i2);
                if (c1 != c2) {
                    c1 = Character.toUpperCase(c1);
                    c2 = Character.toUpperCase(c2);
                    if (c1 != c2) {
                        c1 = Character.toLowerCase(c1);
                        c2 = Character.toLowerCase(c2);
                        if (c1 != c2) {
                            return c1 - c2;
                        }
                    }
                }
            }
            return n1 - n2;
        }
    }

compare还是得比较哪一个大哪一个小吧

相关推荐

Global site tag (gtag.js) - Google Analytics