一、Object
Java API就是JDK中提供给我们使用的类,这些类将底层的代码实现封装了起来,我们不需要关心这些类是如何实现的,只需要学习这些类如何使用即可。
Object类是Java语言中的根类,即所有类的父类。它中描述的所有方法子类都可以使用。
1.1、equals方法
equals方法,用于比较两个对象是否相同,它其实就是使用两个对象的内存地址在比较。Object类中的equals方法内部使用的就是==比较运算符。
在开发中要比较两个对象是否相同,经常会根据对象中的属性值进行比较,也就是在开发经常需要子类重写equals方法根据对象的属性值进行比较。如下代码演示:
/*
描述人这个类,并定义功能根据年龄判断是否是同龄人
由于要根据指定类的属性进行比较,这时只要覆盖Object中的equals方法
在方法体中根据类的属性值进行比较
/* 描述人这个类,并定义功能根据年龄判断是否是同龄人 由于要根据指定类的属性进行比较,这时只要覆盖Object中的equals方法 在方法体中根据类的属性值进行比较 */ class Person extends Object{ int age ; //复写父类的equals方法,实现自己的比较方式 public boolean equals(Object obj) { //判断当前调用equals方法的对象和传递进来的对象是否是同一个 if(this == obj){ return true; } //判断传递进来的对象是否是Person类型 if(!(obj instanceof Person)){ return false; } //将obj向下转型为Perosn引用,访问其属性 Person p = (Person)obj; return this.age == p.age; } }
注意:在复写Object中的equals方法时,一定要注意public boolean equals(Object obj)的参数是Object类型,在调用对象的属性时,一定要进行类型转换,在转换之前必须进行类型判断。
1.2、toString方法
toString方法返回该对象的字符串表示,其实该字符串内容就是对象的类型+@+内存地址值。由于toString方法返回的结果是内存地址,而在开发中,经常需要按照对象的属性得到相应的字符串表现形式,因此也需要重写它。
二、String
字符串是常量;它们的值在创建之后不能更改,这是什么意思呢?其实就是说一旦这个字符串确定了,那么就会在内存区域中就生成了这个字符串。字符串本身不能改变,但str变量中记录的地址值是可以改变的。
String s3 = "abc"; String s4 = new String("abc"); System.out.println(s3==s4);//false System.out.println(s3.equals(s4));//true, //因为String重写了equals方法,建立了字符串自己的判断相同的依据(通过字符串对象中的字符来判断)
s3和s4的创建方式有什么不同呢?
s3创建,在内存中只有一个对象。这个对象在字符串常量池中
s4创建,在内存中有两个对象。一个new的对象在堆中,一个字符串本身对象,在字符串常量池中
String s4 = new String(“abc”);
String s3 = “abc”;
2.1、String类构造方法
String s1 = new String(); //创建String对象,字符串中没有内容 byte[] bys = new byte[]{97,98,99,100}; String s2 = new String(bys); // 创建String对象,把数组元素作为字符串的内容 String s3 = new String(bys, 1, 3); //创建String对象,把一部分数组元素作为字符串的内容,参数offset为数组元素的起始索引位置,参数length为要几个元素 char[] chs = new char[]{’a’,’b’,’c’,’d’,’e’}; String s4 = new String(chs); //创建String对象,把数组元素作为字符串的内容 String s5 = new String(chs, 0, 3);//创建String对象,把一部分数组元素作为字符串的内容,参数offset为数组元素的起始索引位置,参数count为要几个元素 String s6 = new String(“abc”); //创建String对象,字符串内容为abc
2.3 String类方法查找
2.3.1、字符串中有多少个字符
String str = "abcde"; int len = str.length(); System.out.println("len="+len);
2.3.2、获取部分字符串
String str = "abcde"; String s1 = str.substring(1); //返回一个新字符串,内容为指定位置开始到字符串末尾的所有字符 String s2 = str.substring(2, 4);//返回一个新字符串,内容为指定位置开始到指定位置结束所有字符 System.out.println("str="+str); System.out.println("s1="+s1); System.out.println("s2="+s2);
2.3.3、字符串是否以指定字符串开头
String str = "StringDemo.java"; boolean b1 = str.startsWith("Demo");//判断是否以给定字符串开头 boolean b2 = str.startsWith("String"); boolean b3 = str.endsWith("java");//判断是否以给定字符串结尾
2.3.4、字符串中是否包含另一个字符串。
String str = "abcde"; int index = str.indexOf(“bcd”); //判断是否包含指定字符串,包含则返回第一次出现该字符串的索引,不包含则返回-1 boolean b2 = str.contains("bcd");//判断是否包含指定字符串,包含返回true,不包含返回false
2.3.5、将字符串转成一个字符数组。或者字节数组。
String str = "abcde"; char[] chs = str.toCharArray(); byte[] bytes = str.getBytes();
2.3.6、判断两个字符串中的内容是否相同
String str = "abcde"; String str2 = "abcde"; String str3 = "hello"; boolean b1 = str.equals(str2); boolean b2 = str.equals(str3);
2.3.7、获取该字符串对象中的内容
String str = new String("hello"); System.out.println( str.toString() ); System.out.pintln( str );
直接打印引用类型变量时,默认调用该类型进行重写后的toString方法
2.4、代码:
String a="abc"; String b="a"+"bc"; if(a == b) { System.out.print("true"); } else { System.out.print("false"); } //输出为:true //只生成一个字符串,保存在字符串常量池中
2.5、Java的String类型为什么是不可变的
String类中的成员变量:
private final char value[]; private final int offset; private final int count;
执行了String s = “ABCabc”; 这句代码之后,真正的内存布局应该是这样的:
value,offset和count这三个变量都是private的,并且没有提供setValue, setOffset和setCount等公共方法来修改这些值,所以在String类的外部无法修改String。
2.6、不可变的好处
因为字符串是不可变的,所以是多线程安全的,同一个字符串实例可以被多个线程共享。这样便不用因为线程安全问题而使用同步。字符串自己便是线程安全的。
在大量使用字符串的情况下,可以节省内存空间,提高效率。
2.7、String截取字符串
代码:
String str = "www.baidu.com"; int i = str.lastIndexOf('.'); String str1 = str.substring(i+1,str.length()); System.out.println(str1);
2.8、Java如何把byte类型转换成字符串
2.8.1、常规的String转byte[]
代码分析:
public static byte[] strToByteArray(String str) { if (str == null) { return null; } byte[] byteArray = str.getBytes(); return byteArray; }
2.8.2、常规的byte[]转String
代码分析:
public static String byteArrayToStr(byte[] byteArray) { if (byteArray == null) { return null; } String str = new String(byteArray); return str; }
2.8.3、byte[]转化为十六进制的String
代码分析:
private static final String hexDigits[] = {"0", "1", "2", "3", "4", "5","6", "7", "8", "9", "a", "b", "c", "d", "e", "f"}; //单个字节转换成16进制的字符串 private static String byteToHexString(byte b) { int n = b; if (n < 0) n += 256; int d1 = n / 16; //取出高4位 int d2 = n % 16; //取出低4位 return hexDigits[d1] + hexDigits[d2]; } //将字节数组转换成16进制字符串 private static String byteArrayToHexString(byte b[]) { StringBuffer resultSb = new StringBuffer(); for (int i = 0; i < b.length; i++) resultSb.append(byteToHexString(b[i])); return resultSb.toString(); } //测试代码: public static void main(String[] args) { byte[] b = {10,11}; String s = MD5Util.byteArrayToHexString(b); System.out.println(s); } //运行结果: //0a0b
2.8.3、MD5工具类
代码分析:
public class MD5Util { private static String byteArrayToHexString(byte b[]) { StringBuffer resultSb = new StringBuffer(); for (int i = 0; i < b.length; i++) resultSb.append(byteToHexString(b[i])); return resultSb.toString(); } private static String byteToHexString(byte b) { int n = b; if (n < 0) n += 256; int d1 = n / 16; int d2 = n % 16; return hexDigits[d1] + hexDigits[d2]; } public static void main(String[] args) { byte[] b = {10,11}; String s = MD5Util.byteArrayToHexString(b); String s1 = MD5Util.MD5EncodeUtf8("101112a"); System.out.println(s1.length()); } //返回大写MD5 private static String MD5Encode(String origin, String charsetname) { String resultString = null; try { resultString = new String(origin); MessageDigest md = MessageDigest.getInstance("MD5"); if (charsetname == null || "".equals(charsetname)) resultString = byteArrayToHexString(md.digest(resultString.getBytes())); else resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname))); } catch (Exception exception) { } return resultString.toUpperCase(); } public static String MD5EncodeUtf8(String origin) { origin = origin + PropertiesUtil.getProperty("password.salt", ""); return MD5Encode(origin, "utf-8"); } private static final String hexDigits[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};
三、StringBuffer
StringBuffer是个字符串的缓冲区,即就是它是一个容器,容器中可以装很多字符串。并且能够对其中的字符串进行各种操作。
StringBuffer的方法使用
//创建一个字符串缓冲区对象。用于存储数据。 StringBuffer sb = new StringBuffer(); sb.append("haha"); //添加字符串 sb.insert(2, "it");//在指定位置插入 sb.delete(1, 4);//删除 sb.replace(1, 4, "cast");//替换指定范围内的内容 String str = sb.toString();
注意:append、delete、insert、replace、reverse方法调用后,返回值都是当前对象自己,所以说,StringBuffer它可以改变字符序列的长度和内容。
四、StringBuilder类
此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。