package com.atguigu.string;
import org.junit.Test;
import java.io.UnsupportedEncodingException;
/**
* 本来包含String类的所有常用操作。
* 底层实现了Serializable, Comparable接口,这意味着String类可以序列化,可以进行比较。
* String类重写了equals方法,使得equals比较的是字符串的内容,==比较的是地址
* String对象一旦创建,就不可更改故String参与运算,会产生很多新的变量。
* String对象保存的是字符串的地址,new出来的字符串对象在堆中和常量池中保存,不是new出来仅在常量池中保存。
* String底层是一个字符数组 源码中第一条属性:private final char value[];用debug模式可以证明
*String/StringBuilder/StringBuffer:
* String类不可变,String对象被创建后,对象中的字符序列是不可改变的,除非这个对象销毁。
* StringBuilder类可变,可以通过append方法改变其内容再调用toString方法将其转变为String。
* StringBuffer类可变,构造方法和方法与StringBuilder基本相同。不同是StringBuffer线程安全,StringBuilder线程不安全,性能略高
* 通常情况下,创建一个内容可变的字符串,且在单线程环境下,应该优先考虑使用StringBuilder。
*/
public class MyStringTest {
/**
* 字符串拼接的方法,如果第一个参数为null,则无连接符。不为null,则有连接符。
* @param separator 连接符,不需要请传入null值。
* @param strs 字符串数组11111
* @return
*/
public String concat_ws(String separator,String ... strs){
StringBuilder stringBuilder = new StringBuilder();
if(separator == null)
separator="";
for(String str:strs)
stringBuilder.append(str+separator);
String str = stringBuilder.toString();
if (separator != "")
return str.substring(0,str.length()-1);
else
return str;
}
@Test
public void testConcat_ws(){
System.out.println(concat_ws(null,"a","b","c"));
System.out.println(concat_ws("","a","b","c"));
System.out.println(concat_ws("-","a","b","c"));
}
/**
* 字符串翻转。。
*/
public String reverse(String str){
return new StringBuilder(str).reverse().toString();
}
/**
* 测试String类大部分常用方法。
*/
@Test
public void testString() throws UnsupportedEncodingException {
String str="123456qwErt ";
System.out.println(str.toLowerCase());
System.out.println(str.toUpperCase());
System.out.println(str.length());
System.out.println(str.trim());
System.out.println(str.split("q")[0].toString());
System.out.println(str.isEmpty());
System.out.println("123456qwErt ".equals(str));
System.out.println(str.charAt(2));
System.out.println(str.substring(3));
System.out.println(str.substring(3,5));//从0开始,前闭后开
System.out.println(str.replace('q','Q'));
System.out.println(str.replace("qw","QW"));
System.out.println(str.indexOf('q'));
System.out.println(str.indexOf('q',1));
System.out.println(str.lastIndexOf('q'));//lastIndexOf是从右往前检索
System.out.println(str.lastIndexOf('q',9));
System.out.println(str.contains("123"));//是否包含子串
System.out.println(str.endsWith("rt"));//是否以子串结尾
System.out.println(str.compareTo("1234"));//只有父子串返回长度之差。非父子串返回各位ASCII码差之和
System.out.println(str.compareTo("123456rfgvc"));
System.out.println(str.matches("/\\b([a-z]+) \\1\\b/ig"));//字符串是否匹配正则
//转换
System.out.println(str.getBytes("UTF-8"));//转为utf-8编码下的字节数组,可以通过String构造器还原
System.out.println(str.toCharArray().length);//转化为字符数组
System.out.println(String.valueOf(false));//valueOf中可传入任意类型并将其转为String类型
}
/**
* 测试String是否相等
* String类重写了equals方法,使得equals比较的是字符串的内容,==比较的是地址。
* String对象保存的是字符串的地址,new出来的字符串对象在堆中和常量池中保存,不是new出来仅在常量池中保存。
* String对象加法实际操作的是StringBuilder对象的append方法,得到最终字符串后调用toString得到一个新的String对象。
* 该新得到的String字符串只存在堆中,不存在常量池中。
*/
@Test
public void isEquals(){
String c1=new String("abc");
String c2=new String("abc");
String c3="abc";
String c4="abc";
System.out.println("c1和c2保存堆地址不同:"+ (c1==c2));
System.out.println("C3和C4保存的常量池地址一致:"+(c3==c4));
c3=c1;
System.out.println("字符串重新赋值,保存的地址改变:"+(c3==c1));
System.out.println("======================================================");
String str1="ab";//如果字符串常量池有,创建0个对象,否则1个。
String str2="cd";
String str3="abcd";
String str4="ab"+"cd";//java编译器优化成String str4="abcd";所以如果字符串常量池有,创建0个对象,否则1个。
String str5=str1+"cd";//如果字符串常量池有“cd”,创建一个StringBuilder,一个堆中String对象“abcd”,共两个,否则3个。
String str6="ab"+str2;
String str7="a"+"b"+str2+"";//java编译器优化城String str6="ab"+str2+"";
String str8=str1+str2;
System.out.println("true则二者都保存常量池对象的引用"+(str3==str4));
System.out.println("true则二者都保存常量池对象的引用"+(str3==str5));
System.out.println("true则二者都保存常量池对象的引用"+(str3==str6));
System.out.println("true则二者都保存常量池对象的引用"+(str3==str7));
System.out.println("true则二者都保存常量池对象的引用"+(str3==str8));
System.out.println("=====================================");
String s1 = "a" +"b"+"c"; //1个对象,字符串常量池中"abc"
String s2 = "a"; //1个对象,字符串常量池中"a"
//3个对象,堆中StringBuilder “abc”和String "abc",常量池中"bc"
String s3= s2 +"bc";
String s4= s2+"b" +"c"; //3个对象,等同于String s3= s2 +"bc";
//5个对象,堆中StringBuilder "你ab",String "你"、"你ab",常量池中"你"、“b”
String s5 = new String("你") + s2 + "b";
//4个对象,堆中StringBuilder “adf” String "adf" 常量池"d"、"f"
String s6= s2 + "d" +"f" ;
//5个对象,堆中StringBuilder "abcdabc" String "abcdabc",常量池中"abcd"、"b"、“c”
String s7= "ab" + "cd" + s2 + "b" +"c";
}
}
package com.atguigu.string;
import org.junit.Test;
import java.util.Date;
/**
* 本类用于测试String类的format方法
*/
public class MyStringFormatMethodTest {
/**
* 获取时间的方法
*/
@Test
public void formatTime(){
Date date = new Date();
//时间
System.out.println("当前时间:"+String.format("%1$tF-%1$tT",date));//tF代表年月日,tT代表时分秒
System.out.println("当前时间戳:"+String.format("%tQ",date));
System.out.println("当前年份:"+String.format("%tY",date));
System.out.println("当前月份:"+String.format("%tm",date));
System.out.println("当前天数:"+String.format("%td",date));
System.out.println("当前小时数:"+String.format("%tH",date));
System.out.println("当前分数:"+String.format("%tM",date));
System.out.println("当前秒数:"+String.format("%tS",date));
System.out.println("当前毫秒数:"+String.format("%tL",date));
System.out.println("当前时间是一年中第几天:"+String.format("%tj",date));
System.out.println("当前时间是星期几:"+String.format("%tA",date));
}
/**
* 格式化数字:%[index$][标识][最少宽度][.精度]转换方式
* 只有格式化浮点数才有[.精度]这一项。
* [index$]: "1$"表示第一个参数,"2$"表示第二个参数,类推。
* [标识]:
* '-' 在最小宽度内左对齐,不可以与"用0填充"同时使用。
* '+' 正数前显示正号 负数前显示负号(一般情况下只适用于10进制,若对象为BigInteger才可以用于8进制和16进制)。
* ' ' 正值前加空格,负值前加负号(一般情况下只适用于10进制,若对象为BigInteger才可以用于8进制和16进制)。
* '0' 结果将用零来填充。
* ',' 只适用于10进制,每3位数字之间用","分隔。(对于浮点数只适用于fgG的转换)
* '(' 若参数是负数,则结果中不添加负号而是用圆括号把数字括起来(同'+'具有同样的限制)。
* '#' 只适用于8进制和16进制,8进制时在结果前面增加一个0,16进制时在结果前面增加0x。
* [最少宽度]:该数字格式化后的字符串最少占用多少显示长度。
* [.精度]:“.2表示保留两位小数,仅适用于浮点数”
* 转换方式:
* 整数:d-十进制 o-八进制 x或X-十六进制
* 浮点数:e/E 科学记数法 f 普通十进制 g/G自动选择科学记数法还是普通十进制 a/A 十六进制
*/
@Test
public void formatNumber(){
//整数
System.out.println(String.format("%1$-9d", 312356));
System.out.println(String.format("%1$#9x", 312356));
System.out.println(String.format("%1$-#9o", 312356));
System.out.println(String.format("%1$+9d", 312356));
System.out.println(String.format("%1$ 9d", 312356));
System.out.println(String.format("%1$ 9d", -312356));
System.out.println(String.format("%1$09d", 312356));
System.out.println(String.format("%1$,9d", 312356));
System.out.println(String.format("%1$(9d", 312356));
//浮点数
System.out.println("=======================================");
System.out.println(String.format("%1$-9.2f", 3123.32));
System.out.println(String.format("%1$+9.2f", 3123.32));
System.out.println(String.format("%1$ 9.2f", -3123.32));
System.out.println(String.format("%1$ 9.2f", 3123.32));
System.out.println(String.format("%1$09.2f", 3123.32));
System.out.println(String.format("%1$,9.2f", 3123.32));
System.out.println(String.format("%1$(9.2f", -3123.32));
System.out.println(String.format("%1$9.2e", -3123.32));
System.out.println(String.format("%1$9.2f", -3123.32));
System.out.println(String.format("%1$9.2g", -3123.32));
System.out.println(String.format("%1$9.2a", -3123.32));
}
}