运算符
1.==:这个运算符对于基本数据类型(byte、short、int等)比较的是值,对于引用数据类型来说,比较的是地址。
说到了==,一个与之对应的方法就不得不说一下,这个方法就是equals。想必大家都对它有所了解,它比较的就是两个对象之间的值,那它的原理是什么,我们来看看源码。
Integer的equals
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
首先,equals比较的必须是对象。由源码可知,它先做的操作是判断括号里的类型是否是Integer,是->比较值,相等返回true,不等返回false;否->返回false。
其实所有的包装器类的equals都是这样的。那么如果不是包装器类呢?
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
这是String的equals方法。它先判断的是两个对象的地址是否相同,相同返回true。这很好解释,地址相同了,指向的值肯定也相同。如果地址不同,进行下一个判断:判断括号里的对象是不是String类型的,如果是,且长度和括号外的String对象的长度相等,那么就将两个String对象中的每个字符串进行比较,每个字符串都一样,返回true,否则返回false。
ok,那么如果是普通的对象呢?像自定义的Student等,他们的equals是怎样的?
public boolean equals(Object obj) {
return (this == obj);
}
更简单了,直接比较两者地址是否一样。这就是我们在使用Set集合时,为什么要重写自定义类的equals方法和hashCode方法的原因了。hashCode方法可以按照我们的想法指定hashCode值为什么,然后equals比较hashCode,就可以做到不重复的效果。
2.+:它可以做算数+,单纯的+、-、*、/的+;也可以做字符串拼接。所以我们通过例子来了解
System.out.println(1+2+"a"); //3a
System.out.println(1+2.0+"a"); //3.0a
System.out.println(1+"a"+2.0); //1a2.0
System.out.println(1+"a"+2); //1a2
System.out.println("a"+1+2); //a12
System.out.println('a'+1+2); //100 'a'的ASCII码是97
System.out.println('a'+"a"+1+2);//aa12 拼接的时候不会转换成ASCII码
通过上例,我们可以知道的是:
当基本数据类型与基本数据类型+的时候,进行算数运算;当基本数据类型和String类型+的时候,进行字符串拼接。
3.>>、<<、>>>:算数右移、算数座椅、逻辑左移
>>:通俗的来说就是不带符号右移,相当于除以2
<<:不带符号的左移,相当于乘2
>>>:带符号右移,连同符号位一起移。
怎么记>>和>>>呢?我是这么记的:>>只有两个">",而>>>有三个">",所以>>>牛X一点,它可以连符号位一起移动。
System.out.println(10 >> 1); //5
System.out.println(-10 >> 1); //-5
System.out.println(10 << 1); //20
System.out.println(-10 << 1); //-20
System.out.println(10 >>> 1); //5
System.out.println(-10 >>> 1); //2147483643
我们就着重讲一下最后一个吧。首先-10默认是int类型的所以二进制是1000 0000 0000 0000 0000 0000 0000 1010。往右带着符号移一位,就是0100 0000 0000 0000 0000 0000 0000 1010。所以才会的到那个那么大的数字
4.&、|、~、^、&&、||:
&:与 1&1=1,1&0=0,0&0=0,true&true=true,true&false=false,false&false=false
| :或 1|1=1,1|0=1,0|0=0,true|true=true,true|false=true,false|false=false
~:非 ~1=0,~0=1
^:异或 1^1=0,1^0=1,0^0=1
&&:若左边的表达式为false,右边的代码不会执行
|| :若左边的表达式为true,右边的代码不会执行
循环
1for(初始化部分;循环条件;迭代部分){
循环体
}
执行顺序:初始化部分(只执行一次) -> 循环条件 -> 循环体 -> 迭代部分 -> 循环条件 -> 循环体 -> 迭代部分 ........
2.while(循环条件){
循环体,包括迭代部分
}
执行顺序:循环条件 -> 循环体,包括迭代部分 -> 循环条件.........
3.do{
循环体,包括迭代部分
}while(循环条件);
执行顺序:循环体,包括迭代部分 -> 循环条件.........
以上三种可以用continue和break对循环进行操作。
continue:结束本次循环,进行下一次循环。
break:打破循环,即结束整个循环,执行循环之后的代码
还可以加标记,指定结束什么循环,举个栗子:
public class XunHuan {
public static void main(String[] args) {
a:for (int i=0;i<5;i++){
for (int j=0;j<5;j++){
if(j==2){
continue a;
}
System.out.println(j);
}
System.out.println("---------");
}
}
}
a是指定的标记,随便叫什么名字。猜猜如上代码的结果是什么?每当 j等于2的时候,就结束本次循环,进入下一次,而我们在第一层循环左边加了个标记,所以进入的下一次循环是第一层的循环。而且输出的"----------"也不会打印。
switch语句:先说说语法吧。switch语句括号里只允许出现char,byte,short,int,String,enum类型
switch([char,byte,short,int,String,enum]){
case value1:
....;
break; //可以不写,如果不写,不会跳出switch语句。
//当某个case的值满足条件,其后的值都满足条件
case value2:
....;
break;
.........
case valueN:
....;
break;
default:
......;
}
public static void main(String[] args) {
int i = 1;
switch (i){
case 1:
System.out.print(1);
case 2:
System.out.print(2);
case 3:
System.out.print(3);
default:
System.out.print("default");
case 4:
System.out.print(4);
}
}
会输出123default4。