比较原始类型的相等与比较两个对象相等是不同的。如果数值5存放在两个不同的int变量中,比较两个变量是否相等将产生结果为 boolean 值 true:
<ccid_nobr></ccid_nobr>
public class TestIntComparison {
public static void main(String[] args) {
int x = 5, y = 5;
System.out.println(
"x == y yields " + (x == y));
}
}
|
TestIntComparison 产生以下输出:
<ccid_nobr></ccid_nobr>
D:\>java TestIntComparison
x == y yields true
|
相等操作符由于原始类型时比较的是它们的值。而用于对象时比较的是对象的引用而不是对象的实际内容。 您可能问:"这些引用都指向同一个对象么?" 为了说明清晰,请看下面只含有 tag 和 age 的 Dog 的又一版本:
<ccid_nobr></ccid_nobr>
class Dog {
int tag;
int age;
public void setTag(int t) {tag=t;}
public void setAge(int a) {age=a;}
}
|
如果有两只狗(dog),即使它们的内容都相同,用 == 操作符时它们并不相等。下面代码段的输出表明在用 "==" 时 a 和 b 并不相等:
<ccid_nobr></ccid_nobr>
Dog a = new Dog();
a.setTag(23129);
a.setAge(7);
Dog b = new Dog();
b.setTag(23129);
b.setAge(7);
if ( a==b ) {
System.out.println("a is equal to b");
}
else {
System.out.println("a is not equal to b");
}
|
那么,应该怎么比较两个对象的值而不是比较它们的引用呢?Java(TM) 编程语言有一个约定,方法 equals() 用来定义对象值相等。 类 Object 中定义了方法equals(),如果在其子类中没有被重载,那么默认使用的就是它。 为了比较两只狗(dog) a 和 b 的值,你应该重写上面的比较部分:
<ccid_nobr></ccid_nobr>
if ( a.equals(b) ) {
System.out.println("a is equals() to b");
}
else {
System.out.println("a is not equals() to b");
}
|
上面的代码中,如果在 Dog 中没有重载 equals() 方法,两只狗依旧不等。因为 Object.equals() 实际模拟的是 == 操作符的功能。 Dog 中 equals() 的定义很好懂:
<ccid_nobr></ccid_nobr>
class Dog {
int tag;
int age;
public void setTag(int t) {tag=t;}
public void setAge(int a) {age=a;}
public boolean equals(Object o) {
Dog d = (Dog)o;
if ( tag==d.tag && age==d.age ) {
return true;
}
return false;
}
}
|
为什么 equals() 的参数类型是 Object 而不是 Dog 呢?因为你是在重载父类 Object 的方法 equals(),所以必须用相同的方法标记。但我们希望传进的参数是另一只Dog,所以为了能够访问参数的字段需将其类型转换为 Dog。
但是,由于 equals() 是在 Dog 中定义的,你必须检查传入的对象是否是一只 Dog,因为有人可能这样用:
<ccid_nobr></ccid_nobr>
字符串 "blort" 也是一个 Object ,因此与 Dog 中 equals() 的标记是匹配的。equals() 的正确写法是:
<ccid_nobr></ccid_nobr>
public boolean equals(Object o) {
if ( o instanceof Dog ) {
Dog d = (Dog)o;
if ( tag==d.tag && age==d.age ) {
return true;
}
}
// false if not Dog or contents mismatched
return false;
}
|
操作符 instanceof 询问 o 是否是 Dog (包括 Dog 的子类) 的实例。
字符串的比较引入了对象比较的最后一个问题,那就是
"abc"=="def"
表达式的值为 true 还是 false 呢?是false,因为他们是本质都不同的对象(显而易见,他们的内容都不同)。但是,下面的表达式
"abc"=="abc"
是 true 还是 false 呢?不幸的是,这由编译器决定。如果编译器将对 "abc" 的两个引用优化为一个对象而不是两个对象,那么表达式的值为 true。但是,如果编译器不做这种优化,表达式的值则应为 false!
如果你真的想判断两个字符串在物理上是不是同一个对象,请用 equals() 方法:
<ccid_nobr></ccid_nobr>
boolean b = "abc".equals("def"); // false
boolean c = "abc".equals("abc"); // true
|
分享到:
相关推荐
在Java编程语言中,创建这样一个计算器通常需要以下几个关键知识点: 1. **Java基础**:首先,需要扎实的Java基础知识,包括变量、数据类型、控制结构(如if-else,循环)、类和对象等。计算器程序通常会包含一个或...
2. **词法分析**:识别出等式中的数字、变量、运算符和括号。 3. **语法分析**:根据运算符的优先级和结合性进行计算。 对于一个简单的等式,如`2 * (x + 3) - 4 / 2`,解析器可能会先计算括号内的表达式,然后应用...
在这个Java课程设计中,我们将深入探讨如何利用编程技术来实现这样一个游戏。 一、游戏规则 游戏的基本规则是:两人轮流从一堆火柴中取出1至3根,最后取完火柴的人为输家。初始时,系统会随机生成20到50根火柴,...
Java作为一种面向对象的编程语言,在网络应用开发中被广泛采用,并因其开源特性及“一次编写,到处运行”的理念而受到欢迎。 #### 机器语言、汇编语言与高级语言 - **机器语言**:计算机硬件组件的自然语言,具有...
4. **Java实现**:在Java中,你可以创建一个名为`LP`的类,用于处理线性规划问题的标准化、添加人工变量以及两阶段法的计算。`LP`类可能包含以下方法: - `standardize()`: 实现线性规划问题的标准化过程。 - `...
使用1-9这九个数,使该等式()()()()X()=()()()()成立,并且各数值不能重复,乘数、被乘数和积各个数位没有重复的。
综上所述,`java_puzzlers`中文版中的这两个谜题,揭示了Java编程中容易忽视的细节,包括取余运算的符号敏感性和浮点数计算的不精确性。通过深入理解这些问题及其解决方案,开发者可以编写更加健壮和准确的代码。
java版的等式表达式解析,不等式表达式解析,与或非逻辑运算表达式解析;支持带参数的表达式解析; 支持带函数的表达式解析。 1、支持 +、-、*、/、%、&&、||、!、>、<、>=、、==、!=、^(幂)、(、) 运算符 2、支持有...
Java CLP(Coin-OR线性规划)是一个开源的线性规划求解器,它允许开发者在Java环境中解决线性优化问题。CLP是COIN-OR项目的一部分,该项目旨在提供一系列工具和库,支持优化计算的研究和开发。线性规划是一种优化...
此外,还介绍了等式和关系运算符,例如`==`用于比较两个值是否相等,`>`、`、`>=`、`用于比较大小,这些都是决策结构(如if语句)中的关键元素。 (可选案例研究)第2.9节提供了思考对象的方法,通过分析问题陈述来...
java实现google方程式 有一个字符组成的等式:WWWDOT - GOOGLE = DOTCOM,每个字符代表一个0-9之间的数字,WWWDOT、GOOGLE和DOTCOM都是合法的数字,不能以0开头。请找出一组字符和数字的对应关系,使它们互相替换,...
在Eclipse环境中运行Java程序,首先需要在项目中创建源文件,然后通过Eclipse的运行配置执行Java类。 **知识点**: 1. Java基础语法:变量声明、字符串处理。 2. 控制台输出:`System.out.println()`。 3. Eclipse...
接着,讲解了如何声明带有参数的方法,并通过实际例子展示如何在Java中实现方法重载。此外,还介绍了实例变量、设置方法(setter)和获取方法(getter)的使用。本章重点介绍了面向对象编程的基础,强调了封装的概念,是...
在《数据结构与算法分析(Java语言描述)》(第三版)这本教材中,我们看到涉及了关于数据结构、算法以及程序设计的基础概念。在给出的文档中,部分题目和答案涵盖了递归、数学推理、文件处理以及计算理论等多个方面...
在Java编程语言中实现单纯形法,不仅可以提高计算效率,还能为程序员提供灵活的接口,以便在各种实际问题中应用。 1. **线性规划基础**: - 线性规划是优化问题的一个分支,涉及求解一个线性目标函数在一组线性...
逆波兰式,也被称为后缀表达式,是一种用于表示数学表达式的符号表示法。它将操作符放在操作数之后...通过理解逆波兰式的工作原理以及Java中的实现方法,开发者能够更好地掌握数据结构和算法,并应用到各种实际问题中。
在Java中实现线性规划,我们可以利用库如`Apache Commons Math`或`GNU Linear Programming Kit (GLPK)`的Java接口。这些库提供了方便的API来定义目标函数、约束,并求解问题。 使用Apache Commons Math库时,步骤...
特别是前缀++与后缀++的区别,以及等式运算中的转换规则,能够帮助读者在实际编程中避免常见的语法错误,编写出更加优秀的代码。 对于准备参加Java面试的开发者来说,《Java复习宝典_rnxefe版》还提供了一份宝贵的...