程序员语录:
一名优秀的程序员,在穿越单行道时也会确认双向的来车情况。而对于函数,只应该做一件事。做好这件事。只能做这一件事。
1、==和Equals区别
1.1 ==
- 如果比较的是基本数据类型,那么比较的是变量的值。
- 如果比较的是引用数据类型,那么比较的是地址值(两个对象是否指向同一块内存)。
1.2 equals
equals()方法最初在Object类中定义的,默认的实现就是使用==。
如果没重写equals方法比较的是两个对象的地址值。
如果重写了equals方法后我们往往比较的是对象中的属性的内。
基本数据类型包装类是重写了equals 类,如下 Double:
public final class Double extends Number implements Comparable<Double> {
...
public boolean equals(Object obj) {
return (obj instanceof Double)
&& (doubleToLongBits(((Double)obj).value) ==
doubleToLongBits(value));
}
}
public final class Integer extends Number implements Comparable<Integer> {
...
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
}
public final class Float extends Number implements Comparable<Float> {
...
public boolean equals(Object obj) {
return (obj instanceof Float)
&& (floatToIntBits(((Float)obj).value) == floatToIntBits(value));
}
}
2、String、StringBuffer和StringBuilder类的区别
在 Java 中字符串属于对象,String 是 Java 中基础且重要的类,被声明为 final class,是不可变字符串,一旦一个 String 对象被创建以后,包含在这个对象中的字符序列是不可改变的,直至这个对象被销毁。
StringBuffer 就是为了解决大量拼接字符串时产生很多中间对象问题而提供的一个类。它提供了 append 和 add 方法,可以将字符串添加到已有序列的末尾或指定位置,它的本质是一个线程安全的可修改的字符序列。
StringBuilder 类是 JDK 1.5 新增的类,它也代表可变字符串对象。StringBuilder 和 StringBuffer 功能基本相似,方法也差不多。不同的是,StringBuffer 是线程安全的,而 StringBuilder 则没有实现线程安全功能,所以性能略高。
因此在通常情况下,如果需要创建一个内容可变的字符串对象,则应该优先考虑使用 StringBuilder 类。
StringBuffer、StringBuilder、String 中都实现了 CharSequence 接口。CharSequence 是一个定义字符串操作的接口,它只包括 length()、charAt(int index)、subSequence(int start, int end) 这几个 API。
3 StringBuffer 的常用方法如下:
- 反转字符串 public StringBuffer reverse()
- 拼接字符串 public StringBuffer append(String s)
- 删除字符串 public delete(int start, int end)
- 插入 public insert(int offset, int i) ;insert(int offset, String str)
- 替换 replace(int start, int end, String str)
最常用的方法就是 append方法,是在原字符串后直接拼接,可以直接拼接多种类型的参数:
insert 是在指定的位置入字符,可插入的类型也较多:
StringBuffer stringBuffer = new StringBuffer("早起的年轻人");
//拼接 早起的年轻人1234
stringBuffer.append(1234);
//插入 在1号角标处插入新的字符串
stringBuffer.insert(1,"AB");
// 早AB起的年轻人1234
System.out.println(stringBuffer);
replace 是替换指定位置的角标,如要替换范围为[1,2) ,包含1号位,不包含2号位置,代码如下:
StringBuffer stringBuffer = new StringBuffer("早起的年轻人");
//拼接 早起的年轻人1234
stringBuffer.append(1234);
//插入 在1号角标处插入新的字符串
stringBuffer.insert(1,"AB");
// 早AB起的年轻人1234
System.out.println(stringBuffer);
// stringBuffer 这里的内容是 早AB起的年轻人1234
//替换 1号角标上的字符串为 333 (1号角标上的是字符A,将A替换为 333)
stringBuffer.replace(1,2,"333");
System.out.println(stringBuffer);
capacity()方法是用来获取容量:
StringBuffer stringBuffer = new StringBuffer("早起的年轻人");
//当前的容量是 22
int capacity = stringBuffer.capacity();
//
System.out.println("当前的容量是 "+capacity);
返回的当前的容量是22,这是因为调用StringBuffer有参数构造时,默认缓冲区是当前字符串长度再加16,“早起的年轻人”是6个汉字,再加16,缓冲区就是22。这是初始的长度,构造函数如下:
public StringBuffer(String str) {
super(str.length() + 16);
append(str);
}
使用 StringBuffer 默认构造创建对象时,构造方法默认创建16个字符的缓冲区,存放在内部数组,当调用默认构造函数,缓冲区是16个字节。
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("早起的年轻人");
//当前的容量是 16
int capacity = stringBuffer.capacity();
//
System.out.println("当前的容量是 "+capacity);
使用 StringBuffer 默认构造创建对象时,构造方法默认创建16个字符的缓冲区,存放在内部数组,当调用默认构造函数,缓冲区是16个字节,然后再每次append 添加元素时,容量的扩充原理是:
小于当前容量时,容量不变。
大于当前容量,并且小于(当前容量+1)2,则容量变为(当前容量+1)2。
大于当前容量,并且大于(当前容量+1)*2,则容量变为用户所设置的容量。
完毕