课程·面向对象·拾遗

·String类引出的特殊字符处理

  在Unicode中有一类特殊字符:换行符、回车符、制表符等。这类字符可以用以自然语言的单词划分,却不能在单词划分后用作判定单词是否相同的依据。例如:“water\nmelon”与“watermelon”在自然语言中,前者实为两个单词,而后者为一个单词。再如:“speed\n”、“speed”、“\nspeed”三者在自然语言中代表同一个单词,“\n”(换行符)在其中不表意。故在处理与自然语言相关的文本时应注意这类这特殊字符的处理。

  特别注意的是在win系统中文本的换行符为“\r\n”,UNIX系统中为“\n”,MAC系统中为“\r”。其中在win系统下,JAVA输出“\n”与输出“\r\n”的效果相同。其余系统还未测试。

  例1.

    while((temp = reader.read()) != -1){
            //读取单词,逐个字符读取
            if((char)temp == ' ' || (char)temp == '\n'||(char)temp == '\r'||(char)temp == '\t'){
                
                    if(index == 0){
                        continue;
                    }
                    tempWord[index] = '\0';
                    stringSet.myAdd(new String(tempWord,0,index));
                    index = 0;
                
            }
            else{
                tempWord[index++] = (char)temp;
            }
        }

  以上代码来自课堂作业DEBUG1,实现的操作是在一个以空白字符作为分割的字典中读取单词。若不过滤掉其中的“\r”,则可能会出现“aaa\r”的单词,这种单词在JAVA语言中被认为与“aaa”不同,导致与自然语言结果矛盾。而在文本管理器中打开时并不会看到“\r\n”与“\n”有何不同,控制台输出也难以调试。但是可以考虑使用hashCode函数调试这类偏差,有无这类特殊字符能在hashCode所得返回值中体现。

·==,equals(),hashCode()

  对于JAVA的真实运行机制,由于其封装得很好,一般不必了解底层运行机制,但是这里基于现象对JAVA运行机制的假设有助于我对JAVA语言有一个更好的理解。

  首先了解JAVA中基本数据类型与非基本数据类型两种变量的区别。

  JAVA有八种基本数据类型:double, float, int, short, long, byte, char, boolean。这些基本数据类型变量中储存的是“值”本身,即这些变量所指向的运行存储空间中存储的就是这些值本身。而对于非基本数据类型变量,其指向的运行存储空间中存储的是与其关联对象在运行存储空间的地址。这与C++中的指针类似。

  “==”比较的就是两个变量所存储的值是否相同。

int n=6;
int m=6;
System.out.println(n==m);
//ture
String word = new String("neolinsu");
String word1= new String("neolinsu");
String word2 = new String("neolinsu");
System.out.println(word1==word2);
//false  
word1 = word;
word2 = word;
System.out.println(str1==str2); 
//true

 

  如上所示,“n”和“m”为基本数据类型变量,其值皆为“3”,故“==”比较后的返回值为“true”。“word1”和“word2”在初始化时分别与不同的对象关联。虽然这两个对象储存的文本信息相同,皆为“neolinsu”,但这两个不同的对象“地址”不同,导致“word1”和“word2”所直接存储的“地址”值不同,故“==”返回值为“false”。在将“word”的值赋给“word1”和“word2”后,“==”返回值为“true”。

  equals()在Object类中也是比较两个变量是否指向同一对象。而String类中对equals方法进行了重写,若两个变量指向了同一个对象则返回“true”,而若两个变量指向不同对象,而两个不同对象储存的文本信息相同亦返回“true”。否则返回“false”。可见对于String类型,equals()方法不再是比较两个变量存储的地址是否相同,而是比较变量所指对象的特定信息是否相同。对于JAVA中的多数非基本数据类型,equals()皆是比较变量所指对象的特定信息是否相同。

  对于hashCode()有以下协定:

  1.重写了euqls方法的对象必须同时重写hashCode()方法。

  2.如果2个对象通过equals调用后返回是true,那么这个2个对象的hashCode方法返回值(int)相同。

  3.如果2个对象通过equals返回false,他们的hashCode返回的值允许相同。

  String类就对hashCode()进行了重写,使当不同对象所含文本信息相同时hashCode()返回值必定相同,不相同时返回值不一定不同。

 

posted @ 2017-08-07 01:30  neolinsu  阅读(200)  评论(0编辑  收藏  举报