一、String 类
1、创建对象
public static void main(String[] args){
String str1 = "hello";
String str2 = "hello";
String str3 = new String("hello");
String str4 = new String("hello");
System.out.println(str1 == str2);//true
System.out.println(str1 == str3);//false
System.out.println(str3 == str4);//false
/**
* 1、使用String str1 = "hello";这种方式
* 第一次创建str1时,隐式的new一个字符串对象,在运行时常量池中开辟一个空间,来存放新创建的"hello"对象,str1中存放指向这个对象的引用
* 第二次创建str2时,JVM会先在在常量池中查找是否存在相同的常量,若已经存在跟"hello"一样的对象,就直接引用了这个对象,如果没有还是会在运行时常量池中新new一个
* 2、使用String str3 = new String("hello");这种
* 不管堆里面有没有同样的对象,都会在堆内存中新建一个对象,所以str3 和 str4 总会是false
*/
System.out.println(str1.equals(str3));//true
System.out.println(str3.equals(str4));//true
//String类中已经把equals方法重写过了,比较的是具体的值
/**
*String拼接
*/
String s1 = "a"+"b"+"c";
String s2 = "abc";
String s3 = "ab";
String s4 = s3 + "c";
System.out.println(s1==s2);//true
System.out.println(s2 == s4);//false
//先在常量池中创建 abc ,地址指向 s1,也指s2, 再创建 ab ,指向 s3,再创建s4,
//对于 s4,其实是先创建StringBuilder(或 StringBuffer)对象,通过 append 连接得到 abc ,再调用 toString() 转换得到的地址指向 s3。
//所以(s4==s2) 为 false
}
String重写的equals方法
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}
2、常用方法
str : "1abc1239" str.length() :8 str.indexOf("a") :1 str.indexOf('b') :2 str.indexOf(49) :0 str.substring(3) :c1239 str.substring(2, 5) :bc1 str.trim() :1abc1239 str.equals("abc123") :false str.equals("abc123") :false str.toLowerCase() :1abc1239 str.toUpperCase() :1ABC1239 str.charAt(2) :b str.split("c", 2) : 1ab 1239 str.split("c", 1) : 1abc1239 str.getBytes() : 49 97 98 99 49 50 51 57
##注意
str.indexOf(49) :0
这里的index(int)里的int值注意一下
贴一个链接,详细
3、String.format()方法
有两个重载:
String.format(String format, Object... args)
String.format(Locale locale, String format, Object... args)
重点提一下 format 参数的格式:
%[argument_index$][flags][width][.precision]conversion
1、%:必填
2、[argument_index$]:从1开始取值,表示的是拿后面的args中的第几个参数来格式化,默认是按照参数顺序输出
System.out.println(String.format("你好,这是%s,那是%s!", "anna","beta"));//默认按顺序
System.out.println(String.format("你好,这是%2$s,那是%1$s!", "anna","beta"));//按照自定义的顺序
/**
* 你好,这是anna,那是beta!
你好,这是beta,那是anna!
*/
3、[flags]标识:控制输出格式,比如左对齐,三个数用逗号隔开,少位补0等
- '-' 在最小宽度内左对齐,不可以与"用0填充"同时使用
- '#' 只适用于8进制和16进制,8进制时在结果前面增加一个0,16进制时在结果前面增加0x
- '+' 结果总是包括一个符号(一般情况下只适用于10进制,若对象为BigInteger才可以用于8进制和16进制)
- ' ' 正值前加空格,负值前加负号(一般情况下只适用于10进制,若对象为BigInteger才可以用于8进制和16进制)
- '0' 结果将用零来填充
- ',' 只适用于10进制,每3位数字之间用","分隔
- '(' 若参数是负数,则结果中不添加负号而是用圆括号把数字括起来(同'+'具有同样的限制)
System.out.println(String.format("%-3d", 123456789));//123456789
System.out.println(String.format("%011d", 123456789));//00123456789
System.out.println(String.format("%#o", 123456789));//0726746425
System.out.println(String.format("%#x", 123456789));//0x75bcd15
System.out.println(String.format("%+d", 123456789));//+123456789
System.out.println(String.format("%(d", -123456789));//(123456789)
System.out.println(String.format("%,d", 123456789));//123,456,789
4、[width]最小宽度: 输出最小宽度,例如5
5、[.precision] :只有传入参数是浮点数时才有用,传入整数或者日期会抛异常(注意这里前面有个 . )
System.out.println(String.format("%,10.4f", 12345.6789456));//12,345.6789
System.out.println(String.format("%.2f", 12345.6789456));//12345.68
6、conversion转换格式 : 如上转换符所示,s/f等
转 换 符 | 说 明 | 示 例 |
%s | 字符串类型 | "mingrisoft" |
%c | 字符类型 | 'm' |
%b | 布尔类型 | true |
%d | 整数类型(十进制) | 99 |
%x | 整数类型(十六进制) | FF |
%o | 整数类型(八进制) | 77 |
%f | 浮点类型 | 99.99 |
%a | 十六进制浮点类型 | FF.35AE |
%e | 指数类型 | 9.38e+5 |
%g | 通用浮点类型(f和e类型中较短的) | |
%h | 散列码 | |
%% | 百分比类型 | % |
%n | 换行符 | |
%tx | 日期与时间类型(x代表不同的日期与时间转换符
|
conversion差不多看看就行,应该用得多的也就 s/f 啥的
参考文档:
https://blog.csdn.net/jiangyu1013/article/details/52607257
http://kgd1120.iteye.com/blog/1293633
http://www.runoob.com/java/java-string.html
二、StringBuilder和StringBuffer
1、定义
可变字符串
2、String、StringBuilder和StringBuffer 异同
String:字符串常量,不可变,底层用于存放字符的数组是final的,因此只能赋值一次,不能再更改;
StringBuilder:字符串变量,线程不安全,也因此性能高一点,所以单线程操作大量数据就用这个;
StringBuffer:字符串变量,线程安全,可将字符串缓冲区安全的用于多个线程,所以多线程操作大量数据用这个;
3、StringBuffer常用方法
两个可变字符串差不多,最重要的是 toString() 方法,转换成 String 类型;
StringBuffer sb = new StringBuffer();
sb.append("abc123");
System.out.println(sb.toString());//abc123
sb = sb.reverse();
System.out.println(sb.toString());//321cba