基础系列【六】--String
String
1. java.lang.String:代表字符串,继承Object,implements Serializable, Comparable<String>, CharSequence
2. public final class String{}:最终类,不能被继承。
3. 字符串是常量;它们的值在创建之后不能更改。字符串缓冲区支持可变的字符串。因为 String 对象是不可变的,所以可以共享
4. FAQ:字符串为什么是不可变对象?
5. StringBuilder(JDK1.5开始)--最终类,字符串可变的字符序列(可变的缓存数组)。线程不安全的(在单线程下StringBuffer的简易替代)
1. StringBuilder内部维护这一个字符缓冲区。默认初始容量为16。
2. StringBuilder提供了狗杂方法的重载,其中StringBuilder(CharSequence seq)指定传入的字符序列,新建的字符数组的长度为16+seq.length。
3. StringBuilder提供了append和insert重载的方法。用以进行字符串的追加。insert可以指定插入的为值。append只能在字符串的
StringBuilder:中的重要方法
StringBuilder没有重写equals方法
public StringBuilder append()
public StringBuilder insert(int offset, Object obj);
public String toString();
public StringBuilder reverse() 将此字符序列用其反转形式取代。
StringBuilder replace(int start, int end, String str) 使用给定 String 中的字符替换此序列的子字符串中的字符。
StringBuilder delete(int start, int end) 移除此序列的子字符串中的字符。
int length();
int indexOf(String str)
相关代码分析
public static void main(String[] args) {
// 字符串是存储在方法区中,运行时常量池中--常量池。
// s1是直接指向ab在常量池中的地址。改过程创建了一个对象--这个对象存储在常量池中。
String s1 = "ab";
// 首先s2指向了堆内存,堆内存中储存了指向了常量池中的“ab”的地址。
// 在此过程创建了一个对象。
String s2 = new String("ab");
// String s2 = new String("ab");若这句话单独存在,则创建了两个对象,一个对储存在常量池,一个储存在堆内存。
//字面量(直接量)参与运算--如果两个或者两个以上的字面量参与运算,在编译的时候会进行优化。编译之后再赋值。
//String s3 = "a"+"b";编译String s3 = "ab";
String s3 = "a" + "b";
// s4 = s4+b;是一个直接量和一个直接量在运算。
//当成了这种字符串拼接的时候,实际上底层调用了StringBuilder的append()方法。进行拼接
/*StringBuilder sb = new StringBuilder("a").append("b");该结果依然是StringBuilder类型,要要将StringBuilder类型转化为String类型
s4 = sb.toString();--s4 = new String("ab");*/
//此过程产生几个对象?5个对象。
String s4 = "a";
s4 = s4 + "b";
System.out.println(s1 == s2);// false
System.out.println(s1 == s3);// true
System.out.println(s1 == s4);// false
System.out.println(s2 == s3);// false
System.out.println(s2 == s4);// false
System.out.println(s3 == s4);// false
String str1 = new String("H");
String str2 = new String("H");
System.out.println(str1.equals(str2));//true
System.out.println(str1==str2);//false
package stringdemo;
/*
* +:连接符
* StringBuilder append()方法
* 两者性能比较
* */
public class StringDemo2 {
public static void main(String[] args) {
long start = System.currentTimeMillis();
/*String str ="";*/
StringBuilder sb = new StringBuilder();
for(int i=0;i<100000;i++){
/*str+="a";*///执行时间:3283毫秒
sb = sb.append(i);//11毫秒
}
long end = System.currentTimeMillis();
System.out.println("执行时间:"+(end-start));
}
}
String中的方法
1. 重点方法
1. char charAt(int index) 返回指定索引处的 char 值。
2. int length() 返回此字符串的长度
3. StringBuilder reverse() 将此字符序用其反转形式取代。
代码分析
String str= "salkdfsa";
//获取这个字符串对应的字符数组
//FAQ:为什么不反会原数组。而要返回一个新数组?
//1.字符串底层数组不可变且被私有化了。
/*public char[] toCharArray() {
// Cannot use Arrays.copyOf because of class initialization order issues
char result[] = new char[value.length];
System.arraycopy(value, 0, result, 0, value.length);
return result;
}*/
char[] cs = str.toCharArray();
//将字符数组转化为字符串
/*public String(char value[]) {
this.value = Arrays.copyOf(value, value.length);
}*/
str = new String(cs);
public static void main(String[] args) throws UnsupportedEncodingException {
String str1 = "中国";
String str2 = "A";
//比较str1和str2的大小
//int compareTo(String anotherString) 按字典顺序(实际上按照从小到大)比较两个字符串。
//1.将str1和str2在底层转化为字符数组
//2.依次遍历str1和str2数组--{a,s,j,h} {d,j,h,s,a}
//3.将这俩数组对应位置上的数字相减。'a'-'k'=-3
//4.如果差不为0,则将这个数返回,若为0,在依次往后对应位相减。
//5.如果这两个数组前面每位都相等,但有一个数组的先遍历完,则会两个数组长度之差。
System.out.println(str1.compareTo(str2));//32
//6.若返回负数str<str2,返回正数str>str2,返回0str==str2;
//int compareToIgnoreCase(String str) 按字典顺序比较两个字符串,不考虑大小写。
System.out.println(str1.compareToIgnoreCase(str2));//0
/*
* 拼接字符串。并将拼接结果作为新结果返回
public String concat(String str) {
int otherLen = str.length();
if (otherLen == 0) {
return this;
}
int len = value.length;
char buf[] = Arrays.copyOf(value, len + otherLen);
str.getChars(buf, len);
return new String(buf, true);
}
* FAQ:concat和+的区别?
*/
System.out.println(str1.concat(str2));
//boolean contains(CharSequence s) 当且仅当此字符串包含指定的 char 值序列时,返回 true。
//判断中间是否包含
//boolean endsWith(String suffix) 测试此字符串是否以指定的后缀结束。
//判断结尾,例如百度文库--文档类型的筛选
// boolean startsWith(String prefix) 测试此字符串是否以指定的前缀开始。
//判断开头, 常应用到检索
//字符串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;
}*/
System.out.println(str1.equals(str2));
//不考虑大小写比较两个字符串,常用:验证码的验证
System.out.println(str1.equalsIgnoreCase(str2));
//获取字符串的哈希码
//FAQ:为什么相同字符串在任何场景下的哈希码都是一样的?而其他对象的则随条件的改变而改变?
//这是因为String中对hashcode方法做了重写。
System.out.println("abc".hashCode());
System.out.println(new Object().hashCode());
// public byte[] getBytes() 将字符串转化--对应的字节数组
byte[] bs =str1.getBytes("utf-8");
System.out.println(Arrays.toString(str1.getBytes("utf-8")));//[-28, -72, -83]
//将字符数组转化为字符串
System.out.println(new String(str1.getBytes("utf-8"),"utf-8"));
//指定数组中第几个位置元素开始,转化几个字节,指定编码格式。
//表示从bs,0个字节开始按照utf-8编码格式,转换3个字节
String str3 = new String(bs, 0,3,"utf-8");
System.out.println(str3);
//任何一个英文在任何码表中只占一个字节。
//int indexOf(int ch) 返回指定字符在此字符串中第一次出现处的索引。
str1 = "sad;ljdf";
System.out.println(str1.indexOf('d'));//默认位置0开始检索,第一次出现的位置
System.out.println(str1.indexOf('d',5));//指定下标检索开始位置
String s1 = "abc";
String s2 = new String("abc");
System.out.println(s1==s2);//false
//将字符串"abc"强制放入常量池,假如常量池中已经有"abc",则会把"abc"的地址直接赋值给s2
s2 = s2.intern();
System.out.println(s1==s2);//true
//判断是否为空
/*String s3=null;
System.out.println(s3.isEmpty());//NullPointerException*/
String s4 = new String();//""
System.out.println(s4.equals(""));//true
String s5 = "lksajdfkj;lsadf;lkj";
//public String replace(char oldChar, char newChar)
//将字符a替换为+
System.out.println(s5.replace('a', '+'));
//从指定位置截取一个子字符串
System.out.println(s5.substring(2));
//截取从下标开始到第几位,含头不含为。
System.out.println(s5.subSequence(1, 6));
//将字符串转化为全大(小)写
System.out.println(s5.toUpperCase());
System.out.println(s5.toLowerCase());
//去掉这个字符串前后的空白字符 "" '\t' '\r' '\n'--掐头去尾
s5 = " sajfd\t\r\n ";
System.out.println(s5.trim());
//若果是字符数组,调用valueOf(),则是把字符数组的内容打印出来
//若是其他数组,valueOf()底层调用的是toString()
int[] arr = new int[5];
char[] c = {'a','c','d'};
/*public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}*/
System.out.println(String.valueOf(arr));
/*public static String valueOf(char data[]) {
return new String(data);
}*/
System.out.println(String.valueOf(c));
}
下一篇:
基础系列【七】–Object