最近在看Java核心技术这本书,这里对第三章个人认为的重难点做一个总结。方便以后回顾,个人能力有限,本人菜鸟,大神勿喷,请大家多多指教。
一、位运算符 指定 A = 66(0100 0010); B = 22 (0001 0110)(这里为了简化说明支取一个字节即8位来运算)
位运算符比一般的算术运算符速度要快,而且可以实现一些算术运算符不能实现的功能。如果要开发高效率程序,位运算符是必不可少的。位运算符用来对二进制位进行操作,包括:按位与(&)、按位或(|)、按位异或(^)、按位取反(~)、按位左移(<<)、按位右移(>>)。下面就给大家介绍位运算符的详细用法。
按位与(&)(双1为真)
对两个数进行操作,将其转换为二进制
然后这两个数相同位置上的数字为1则值对应位置上的值为1,如下图:
(A & B) 结果为 2, 二进制为 0000 0010
按位或(|)(有1为真)
对两个数进行操作,将其转换为二进制
然后这两个数相同位置上的数字不为零(有一个或者都为1)则值对应位置上的值为1,如下图:
(A | B) 结果为 86, 二进制为 0101 0110
按位异或(^)(不同为真)
对两个数进行操作,将其转换为二进制
然后这两个数相同位置上的数字不同则值对应位置上的值为1,如下图:
(A ^ B) 结果为 84, 二进制为 0101 0100
按位取反(~)
对一个操作数的每一位都取反,如下图:
(~A ) 结果为 -67, 二进制为 1011 1101
(关于按位取反这还涉及到原码反码补码我准备下次单独写一篇相关的文章)
按位左移(<<)
将操作数的所有位向左移动指定的位数。
下图展示了11111111 << 1(11111111 左移一位)的结果。蓝色数字表示被移动位,灰色表示被丢弃位,空位用橙色的0填充。
(A << 2)结果为 8, 二进制为 0000 0100
按位右移(<<)
将操作数的所有位向又移动指定的位数。
下图展示了11111111 >> 1(11111111 右移一位)的结果。蓝色数字表示被移动位,灰色表示被丢弃位,空位用橙色的0填充。
A >> 2 结果为 15, 二进制为 0000 1111
二、枚举类型
有时候,变量的取值只在一个有限的集合内,例如服装的尺码只有S,M,L,X四个号码。针对这种情况,可以使用自定义枚举类型。
enum Size {SMALL,MEDIUM,LARGE,EXTRA_LARGE};
//现在就可以声明这种类型的变量
Size s = Size.MEDIUM;(变量s只能存储这个类型声明中给定的某个枚举值,或者null,null表示这个变量没有设置任何值。)
三、不可变字符
Java的String类是不可变类,并且被final修饰,无法继承。 字符串对象都是不可变对象,所以对字符串进行操作时,都是返回新的字符串对象,原有字符串不会改变。如同数字3永远是数字3。
四、equals与==
操作符比较的是变量值是否相同,因为字符串是引用类型,所以操作符只能检测两个字符串是否指向同一个引用(对象地址),但无法检测字符串对象的内容,完全有可能将内容相同的多个字符串拷贝放置在不同的位置上(对象地址)。操作符==只能用于判断基本类型以及引用类型是否为null。
要判断两个字符串变量是否相同,应该使用equals()方法来判断。两个对象指向同一引用,则说明内容相等。否则开始循环比较字符串内容。String的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 s = "This is String";
String s1 = s + ""; //产生一个新字符串
System.out.println(s == s1); //两个字符串对象非同一个引用,返回false
System.out.println(s.equals(s1)); //两个字符串对象的内容相等,返回true
五、String的常用API
length() //返回字符串中的字符数,即字符串长度。
charAt(int index) //根据索引位置,返回对应字符。
toLowerCase() //把字符串中所有字母字符变成小写。
toUpperCase() //把字符串中所有字母字符变成大写。
toCharArray() //把字符串转成字符数组,即一个字符对应一个字符数组元素。
trim() //消除字符串的两边空白字符。
equals(Object anObject) //判断当前字符串对象与指定对象是否相等。
equalsIgnoreCase(String anotherString) //判断当前字符串对象与指定String 对象是否相等,忽略大小写。
compareTo(String anotherString) //按字典顺序比较两个字符串。
compareToIgnoreCase(String str) //按字典顺序比较两个字符串,忽略大小写
boolean startsWith(String prefix) //判断是否以指定字符串作为前缀
boolean startsWith(String prefix, int toffset) //从指定的索引处开始,判断是否以指定字符串作为前缀
boolean endsWith(String suffix) //当前字符串是否以指定字符串作为后缀。
contains(CharSequence s) //如果包含指定字符串,则返回 true。否则false
substring(int beginInde [,int endIndex]) //返回一个新的字符串。这个字符串包含原始字符串中从beginIndex到串尾或endIndex-1的所有代码单元
split(String regex [,int limit]) //将这个字符串拆分为给定的 regular expression的匹配。
join(CharSequence delimiter,CharSequence ... elements) //返回一个新字符串,用给定的定界符连接所有元素
六、String、StringBuilder与StringBuffer的区别
String:
是对象不是原始类型.
为不可变对象,一旦被创建,就不能修改它的值.
对于已经存在的String对象的修改都是重新创建一个新的对象,然后把新的值保存进去.(对内存与性能有极大的消耗)
String 是final类,即不能被继承.
StringBuffer:
是一个可变对象,当对他进行修改的时候不会像String那样重新建立对象,他是线程安全的。(性能有较小的损失,多线程使用)
它只能通过构造函数来建立,可以通过append来进行字符串的拼接
StringBuilder :
在 Java 5 中被提出,它和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。
由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。
七、Java中的“goto”语句
goto语句在java中作为保留字,并没有实现它。但在其他语言中(c语言),goto是个合法的关键字
java中支持的break和continue虽然能实现goto语句的功能但是我个人总结他们的用法大同小异
首先在java中对标签的要求非常严格
标签必须在一个循环的前面,意思是这个循环的名字叫outer(假设标签名为outer),并且这一行后面不能有任何语句了;
而break和continue是和循环语句结合使用的,因此实际上语句标签的使用也是和循环紧密结合的。
事实上,可以将标签应用到任何语句中,如if语句或者快语句,注意:只能跳出语句块,而不能跳入语句块
而(c语言)goto的用法则比较灵活,(c语言)中的标号可以在任意一个合法语句的前面
因此goto可以在一个函数(c语言)中任意位置跳转(当然不能违反goto语句的合理用法例如不能再嵌套之间跳转等)
因此 个人总结
带标号的break、continue局限于循环体中跳转
带标号的goto 可以在整个方法中(c语言函数)跳转
goto比带标号的break、continue用法灵活 正因为太灵活了
使程序的逻辑结构变的复杂,流程不够清晰,程序的可读性下降
所以java中把goto 保留了
八、Arrays类的常用方法
Arrays.sort(a); //一种高效的排序方式,比传统的快排效率要更高
System.out.println(Arrays.toString(a)); //toString方法 转换格式
Arrays.binarySearch(a,43); //二分查找 就是普通的二分查找 没有很特别的地方
int []b = Arrays.copyOf(a,20); //数组的复制 复制的时候,需要指定数组的大小
Arrays.fill(a,20); //填充 将数组的每一个值都用传入的参数进行替换填充
ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(stringArray)); //asList() 将数组转成List
boolean b = Arrays.asList(stringArray).contains("43"); //检查数据中是否包含某个值
int[] removed = ArrayUtils.removeElement(a, 3); //移除元素
九、不规则数组的本质
Java实际上没有多维数组,只有一位数组。多维数组被解释为“数组的数组”。
例如数组array[3][3],实际上是一个包含3个元素的数组,而每一个元素又是一个由数组构成