写在前面:
整个过程,思考及举例,都在代码中完成,复制代码去执行,更能帮助你理解
代码:
/**
* String相等的判断方式
*/
import java.util.Scanner;
public class StringEqual{
public static void main(String[] args) {
/**
* 先引入一个案例:
* 事先定义一个学科美术,让输入者猜测定义的是什么学科,
* 如果猜对就输出"good";猜错输出"bad"
*/
String subject = "美术";//美术学科是谜底
System.out.print("请输入您的猜测:");
Scanner scanner = new Scanner(System.in);
String guess = scanner.next();//猜测者输入一个学科
System.out.print("这是是使用==比较的结果:");
if(guess == subject){
System.out.println("good");
}else{
System.out.println("bad");
}
// 我以为可是实现输入美术就能判断相等
// 但是,字符串的==判断的是,两个字符串是否指向同一个字符串对象
// String subject = "美术";使得一个新的字面量出现在字符串常量池中
// String guess = scanner.next();新输入的字符串,是一个新的对象,并不是引用池中的那个
// 所以两者就不是指向同一个字符串对象,虽然值都为"美术",但却是两个对象
/**
* 针对以上问题,由两个方向的解决思路:
* 1.改变比较方式,直接比较字符串的状态值,也有多种方式
* 2.使不在池中的字符串,通过String.intern();方法,使它也出现在池中,这样就指向同一对象了
*/
// 1.改变比较方式,直接比较字符串的值
// 1.1 String.equals(Object)
// 源码函数原型:public boolean equals(Object anObject){}
// 函数描述:
/* Compares this string to the specified object. The result is {@code
true} if and only if the argument is not {@code null} and is a {@code
String} object that represents the same sequence of characters as this
object.
*/
// equals
System.out.print("这是使用String.equals()比较的结果:");
if(guess.equals(subject)){//if represents the same sequence of characters
System.out.println("good");
}else{
System.out.println("bad");
}
// equalsIgnoreCase,对于汉语来说,没有大小写之分,也就一样可以用
System.out.print("这是使用String.equalsIgnoreCase()比较的结果:");
if(guess.equalsIgnoreCase(subject)){
System.out.println("good");
}else{
System.out.println("bad");
}
/*
public int compareTo(String anotherString) {}
根据源码可以知道,如果返回值是0,则代表两者一定相同
compareTo功能可以涵盖equals,但这也意味着更多的操作,
只是比较是否相等的话还是用equals
*/
// 使用compareTo,肯定是能成功的
System.out.print("这是使用String.compareTo()比较的结果:");
if(guess.compareTo(subject) == 0){
System.out.println("good");
}else{
System.out.println("bad");
}
// 还有个compareToIgnoreCase,汉语无大小写,在这里肯定也能用
System.out.print("这是使用String.compareToIgnoreCae()比较的结果:");
if(guess.compareToIgnoreCase(subject) == 0){
System.out.println("good");
}else{
System.out.println("bad");
}
// trim方法是修剪的的意思,不修剪就返回原对象,因此在此题中不会奏效
// 在网上看到有人说这种方法可取,因此试了一试
// 再多一嘴,trim修剪的是ASCII<=32(空格)的字符,
// 注意:只是修剪首、尾,字符串中间的不修剪,这一点在源码中很清晰
System.out.print("这是使用String.trim()后比较的结果:");
if(guess.trim() == subject.trim()){
System.out.println("good");
}else{
System.out.println("bad");
}
// 2.使双方都进入常量池中,也就指向了同一个字面量对象了,用==就可以判断是否相等
// 因为常量池帮我们做了字符串比较的工作,相同的字符串,在池中只能有一个实例对象
// 由此引出函数 public native String intern();
// 它在String对象的原码最底部,就这一句代码,其中native我现在还不知道啥意思,先不管
/**
* public native String intern();
* 函数描述:(来自源码)
* A pool of strings, initially empty, is maintained privately by the
* class {@code String}.
* When the intern method is invoked,
* if the pool already contains a string equal to this {@code String} object,
* then the string from the pool is returned
* Otherwise, this {@code String} object is added to the pool and
* a reference to this {@code String} object is returned.
* 结果及作用:
* It follows that for any two strings {@code s} and {@code t},
* {@code s.intern() == t.intern()} is {@code true}
* if and only if {@code s.equals(t)} is {@code true}.
*
*/
// 因此,使用String.intern()是一定成功的
System.out.print("这是是使用String.intern()比较的结果:");
if(guess.intern() == subject.intern()){
System.out.println("good");
}else{
System.out.println("bad");
}
}
}
运行结果:
>javac StringEqual.java
>java StringEqual
请输入您的猜测:美术
这是是使用==比较的结果:bad
这是使用String.equals()比较的结果:good
这是使用String.equalsIgnoreCase()比较的结果:good
这是使用String.compareTo()比较的结果:good
这是使用String.compareToIgnoreCae()比较的结果:good
这是使用String.trim()后比较的结果:bad
这是是使用String.intern()比较的结果:good