📄 chapter03.html
字号:
<A NAME="Index120"></A>C++.
</FONT><A NAME="_Toc375545252"></A><A NAME="_Toc408018453"></A><BR></P></DIV>
<A NAME="Heading106"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
Relational operators<BR><A NAME="Index121"></A><A NAME="Index122"></A></H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Relational operators generate a
<B>boolean</B> result. They evaluate the relationship between the values of the
operands. A relational expression produces <B>true</B> if the relationship is
true, and <B>false</B> if the relationship is untrue. The relational operators
are less than (<)<A NAME="Index123"></A>, greater than
(>)<A NAME="Index124"></A>, less than or equal to
(<=)<A NAME="Index125"></A>, greater than or equal to
(>=)<A NAME="Index126"></A>, equivalent (==)<A NAME="Index127"></A> and not
equivalent
(!=)<A NAME="Index128"></A>.<A NAME="Index129"></A><A NAME="Index130"></A><A NAME="Index131"></A><A NAME="Index132"></A><A NAME="Index133"></A><A NAME="Index134"></A>
Equivalence and nonequivalence works with all built-in data types, but the other
comparisons won’t work with type <B>boolean</B>.</FONT><BR></P></DIV>
<A NAME="Heading107"></A><FONT FACE = "Verdana"><H4 ALIGN="LEFT">
Testing object
equivalence<BR><A NAME="Index135"></A><A NAME="Index136"></A></H4></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The relational operators <B>==</B>
and <B>!=</B> also work with all objects, but their meaning often confuses the
first-time Java programmer. Here’s an example:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: Equivalence.java</font>
<font color=#0000ff>public</font> <font color=#0000ff>class</font> Equivalence {
<font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
Integer n1 = <font color=#0000ff>new</font> Integer(47);
Integer n2 = <font color=#0000ff>new</font> Integer(47);
System.out.println(n1 == n2);
System.out.println(n1 != n2);
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The expression
<B>System.out.println(n1 == n2)</B> will print out the result of the
<B>boolean</B> comparison within it. Surely the output should be <B>true</B> and
then <B>false</B>,<B> </B>since both <B>Integer</B> objects are the same. But
while the <I>contents</I> of the objects are the same, the
<A NAME="Index137"></A><A NAME="Index138"></A>handles are not the same and the
operators <B>==</B> and <B>!= </B>compare object handles. So the output is
actually <B>false</B> and then <B>true</B>. Naturally, this surprises people at
first.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">What if you want to compare the
actual contents of an object for equivalence? You must use the special method
<A NAME="Index139"></A><A NAME="Index140"></A><B>equals( )</B> that exists
for all objects (not <A NAME="Index141"></A>primitives, which work fine with
<B>==</B> and <B>!=</B>). Here’s how it’s used:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: EqualsMethod.java</font>
<font color=#0000ff>public</font> <font color=#0000ff>class</font> EqualsMethod {
<font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
Integer n1 = <font color=#0000ff>new</font> Integer(47);
Integer n2 = <font color=#0000ff>new</font> Integer(47);
System.out.println(n1.equals(n2));
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The result will be <B>true</B>, as
you would expect. Ah, but it’s not as simple as that. If you create your
own class, like this:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: EqualsMethod2.java</font>
<font color=#0000ff>class</font> Value {
<font color=#0000ff>int</font> i;
}
<font color=#0000ff>public</font> <font color=#0000ff>class</font> EqualsMethod2 {
<font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
Value v1 = <font color=#0000ff>new</font> Value();
Value v2 = <font color=#0000ff>new</font> Value();
v1.i = v2.i = 100;
System.out.println(v1.equals(v2));
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">you’re back to square one:
the result is <B>false</B>. This is because the default behavior of
<B>equals( )</B> is to compare handles. So unless you <I>override</I>
<B>equals( )</B> in your new class you won’t get the desired
behavior. Unfortunately, you won’t learn about overriding until Chapter 7,
but being aware of the way <B>equals( )</B> behaves might save you some
grief in the meantime.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Most of the Java library classes
implement <B>equals( )</B> so that it compares the contents of objects
instead of their
handles.</FONT><A NAME="_Toc375545253"></A><A NAME="_Toc408018454"></A><BR></P></DIV>
<A NAME="Heading108"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
Logical operators<A NAME="Index142"></A><A NAME="Index143"></A></H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The logical operators AND
(&&)<A NAME="Index144"></A><A NAME="Index145"></A>, OR
(||)<A NAME="Index146"></A><A NAME="Index147"></A> and NOT (!) produce a
<B>boolean</B> value of <B>true</B> or <B>false</B>
<A NAME="Index148"></A><A NAME="Index149"></A>based on the logical relationship
of its arguments. This example uses the relational and logical
operators:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: Bool.java</font>
<font color=#009900>// Relational and logical operators</font>
<font color=#0000ff>import</font> java.util.*;
<font color=#0000ff>public</font> <font color=#0000ff>class</font> Bool {
<font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
Random rand = <font color=#0000ff>new</font> Random();
<font color=#0000ff>int</font> i = rand.nextInt() % 100;
<font color=#0000ff>int</font> j = rand.nextInt() % 100;
prt(<font color=#004488>"i = "</font> + i);
prt(<font color=#004488>"j = "</font> + j);
prt(<font color=#004488>"i > j is "</font> + (i > j));
prt(<font color=#004488>"i < j is "</font> + (i < j));
prt(<font color=#004488>"i >= j is "</font> + (i >= j));
prt(<font color=#004488>"i <= j is "</font> + (i <= j));
prt(<font color=#004488>"i == j is "</font> + (i == j));
prt(<font color=#004488>"i != j is "</font> + (i != j));
<font color=#009900>// Treating an int as a boolean is </font>
<font color=#009900>// not legal Java</font>
<font color=#009900>//! prt("i && j is " + (i && j));</font>
<font color=#009900>//! prt("i || j is " + (i || j));</font>
<font color=#009900>//! prt("!i is " + !i);</font>
prt(<font color=#004488>"(i < 10) && (j < 10) is "</font>
+ ((i < 10) && (j < 10)) );
prt(<font color=#004488>"(i < 10) || (j < 10) is "</font>
+ ((i < 10) || (j < 10)) );
}
<font color=#0000ff>static</font> <font color=#0000ff>void</font> prt(String s) {
System.out.println(s);
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">You can apply AND, OR, or NOT to
<B>boolean</B> values only. You can’t use a non-<B>boolean</B> as if it
were a <A NAME="Index150"></A><B>boolean</B> in a logical expression as you can
in C and C++. You can see the failed attempts at doing this commented out with a
<B>//!</B> comment marker. The subsequent expressions, however, produce
<B>boolean</B> values using relational comparisons, then use logical operations
on the results.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">One output listing looked like
this:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE>i = 85
j = 4
i > j is <font color=#0000ff>true</font>
i < j is <font color=#0000ff>false</font>
i >= j is <font color=#0000ff>true</font>
i <= j is <font color=#0000ff>false</font>
i == j is <font color=#0000ff>false</font>
i != j is <font color=#0000ff>true</font>
(i < 10) && (j < 10) is <font color=#0000ff>false</font>
(i < 10) || (j < 10) is <font color=#0000ff>true</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Note that a <B>boolean</B> value is
automatically converted to an appropriate text form if it’s used where a
<B>String</B> is expected.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">You can replace the definition for
<B>int</B> in the above program with any other primitive data type except
<B>boolean</B>. Be aware, however, that the comparison of floating-point numbers
is very strict. A number that is the tiniest fraction different from another
number is still “not equal.” A number that is the tiniest bit above
zero is still nonzero.<A NAME="Index151"></A></FONT><BR></P></DIV>
<A NAME="Heading109"></A><FONT FACE = "Verdana"><H4 ALIGN="LEFT">
Short-circuiting</H4></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">When dealing with
<A NAME="Index152"></A><A NAME="Index153"></A>logical operators you run into a
phenomenon called “short circuiting.” This means that the expression
will be evaluated only until the truth or falsehood of the entire expression can
be unambiguously determined. As a result, all the parts of a logical expression
might not be evaluated. Here’s an example that demonstrates
short-circuiting:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: ShortCircuit.java</font>
<font color=#009900>// Demonstrates short-circuiting behavior</font>
<font color=#009900>// with logical operators.</font>
<font color=#0000ff>public</font> <font color=#0000ff>class</font> ShortCircuit {
<font color=#0000ff>static</font> <font color=#0000ff>boolean</font> test1(<font color=#0000ff>int</font> val) {
System.out.println(<font color=#004488>"test1("</font> + val + <font color=#004488>")"</font>);
System.out.println(<font color=#004488>"result: "</font> + (val < 1));
<font color=#0000ff>return</font> val < 1;
}
<font color=#0000ff>static</font> <font color=#0000ff>boolean</font> test2(<font color=#0000ff>int</font> val) {
System.out.println(<font color=#004488>"test2("</font> + val + <font color=#004488>")"</font>);
System.out.println(<font color=#004488>"result: "</font> + (val < 2));
<font color=#0000ff>return</font> val < 2;
}
<font color=#0000ff>static</font> <font color=#0000ff>boolean</font> test3(<font color=#0000ff>int</font> val) {
System.out.println(<font color=#004488>"test3("</font> + val + <font color=#004488>")"</font>);
System.out.println(<font color=#004488>"result: "</font> + (val < 3));
<font color=#0000ff>return</font> val < 3;
}
<font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
<font color=#0000ff>if</font>(test1(0) && test2(2) && test3(2))
System.out.println(<font color=#004488>"expression is true"</font>);
<font color=#0000ff>else</font>
System.out.println(<font color=#004488>"expression is false"</font>);
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Each test performs a comparison
against the argument and returns true or false. It also prints information to
show you that it’s being called. The tests are used in the
expression:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#0000ff>if</font>(test1(0) && test2(2) && test3(2))</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">You might naturally think that all
three tests would be executed, but the output shows otherwise:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE>test1(0)
result: <font color=#0000ff>true</font>
test2(2)
result: <font color=#0000ff>false</font>
expression is <font color=#0000ff>false</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The first test produced a
<B>true</B> result, so the expression evaluation continues. However, the second
test produced a <B>false</B> result. Since this means that the whole expression
must be <B>false</B>, why continue evaluating the rest of the expression? It
could be expensive. The reason for short-circuiting, in fact, is precisely that;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -