String:字符串是不变的;它们的值在创建后无法更改,是线程安全的。 String类主要用于对字符串内容的检索、比较等操作,操作的结果通常得到一个新字符串,但不会改变源串的内容 .
1.构造函数,
新创建的字符串是参数字符串的副本。除非需要original的显式副本,否则使用这个构造函数是不必要的,因为字符串是不可变的。
2.字符串的连接:+
3.字符串的转换:toString()
4.字符串的比较:equals()——将此字符串与指定的对象进行比较。当且仅当参数不是{null},并且是一个代表与此对象相同字符序列的字符串对象,结果是{@code * true}
5.hashCode(),散列值,一般重写equals就重写该方法.
6.compareTo()
7.字符串操作:indexOf()ength(),isEmpty(),charAt(),getChars(),substring(),replace(),matches(),contains(),split(),join(),toLowerCase(),toUpperCase(),trim()
8.startsWith(),endsWith(),可以利用该方法判断前缀和后缀
Object类是类层次结构的根,即所有类的最终祖先,Java中的类都是Object类的直接或间接子类.
Object类中的equals()方法:
public boolean equals(Object obj) {
return (this == obj);
}
在定义类时建议重写equals()方法,String中重写的equals()方法:
public boolean equals(Object anObject) {
if (this == anObject) { //初始判断与Object中一样
return true;
}
if (anObject instanceof String) { //判断是否为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;
}
注意:从上面的例子,我们可以总结出重写equals()方法的诀窍:
1).检查是否为这个对象的引用,可以使用”==“操作符检查
2).检查是否为同一个类型,可以使用instanceof操作符,也可以使用getClass()进行判断
3).如果是同一个类型,则对该类的属性进行比较
4).并且在覆盖equals时总要覆盖HashCode()。
java中创建的对象是保存到堆中的,为了提高查找的速度而使用了散列查找。散列查找的基本思想是定义一个键来映射对象所在的内存地址。当需要查找对象时,直接查找键即可。查看散列码:将重写equals方法时使用的成员变量乘以不同的质数然后求和,作为新的哈希码.
String类中重写的hashCode()方法:
public int hashCode() {
int h = hash; //缓存字符串的哈希码
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
Java中规定,两个内容相同(equals()为true)的对象必须具有相等的hashCode。 因为如果equals为true而两个对象的hashCode不同,那么在整个存储过程中就发生了悖论。
示例代码:
public class EmployeeSimple implements Cloneable {
private String name;
private int age;
public EmployeeSimple() {
}
public EmployeeSimple(String name, int age) {
this.name = name;
this.age = age;
}
//省略get,set...
@Override
public boolean equals(Object obj) {
// 检查是否为这个对象的引用,可以使用”==“操作符检查
if (this == obj) // 如果两个员工是同一个对象则相同
return true;
// 对于任何非空引用值x,x.equals(null)应该返回false
if (obj == null)// 如果两个员工有一个为null则不同
return false;
//检查是否为同一个类型,可以使用instanceof操作符,也可以使用getClass()进行判断
if (getClass() != obj.getClass())
return false;
EmployeeSimple employee = (EmployeeSimple) obj;
//对该类的属性进行比较
return (getName().equals(employee.getName())) && (getAge() == employee.getAge());
}
// 并且在覆盖equals时总要覆盖HashCode()。
@Override
public int hashCode() {
return 7 * name.hashCode() + 11 * new Integer(age).hashCode();
}
public String toString() {
return "姓名:" + getName() + ",年龄:" + getAge();
}
}
测试:
public static void main(String[] args) {
EmployeeSimple employee1 = new EmployeeSimple("张三", 26);
System.out.println("emp1" + employee1);
EmployeeSimple employee2 = new EmployeeSimple("张三", 26);
System.out.println("emp2" + employee2);
EmployeeSimple employee3 = new EmployeeSimple("李四", 20);
System.out.println("emp3" + employee3);
System.out.println("employee1.equals(employee2):" + (employee1.equals(employee2)));
System.out.println("employee1.equals(employee3):" + (employee1.equals(employee3)));
System.out.println("emp1 HashCode:"+employee1.hashCode());
System.out.println("emp2 HashCode:"+employee2.hashCode());
System.out.println("emp3 HashCode:"+employee3.hashCode());
}