java基础进阶篇(一)_String ------【java源码栈】
前言
原生态的String 提供了很多好用的冷门重载方法…
通过不同参数可以节约代码,一行实现我们想要的效果.
ver. JDK1.8
一.构造方法
String本身是final类型,不可继承,不可变更. 创建String 对象有两种:
使用构造方法new String();
直接定义String str = "abc";
构造方法有重载方法,
1.参数为空
public String()
1String str1 = new String();
2.参数是普通字符串
public String(String original);
1String str2 = new String("abc");
2System.out.println("str2= " + str2);
3.参数为char 类型数组, 此构造方法有两种选择
String(char value[])
String(char value[], int offset, int count)
offset:数组的起始下标索引
count:选择的字符个数
1char[] c1 = { 'a', 'b', 'c' };
2String str3 = new String(c1);
3System.out.println("str3= " + str3);
4String str4 = new String(c1, 1, 2);
5System.out.println("str4= " + str4);
4.参数为int 类型数组
public String(int[] int, int offset, int count)
int: 数组 offset: 开始处索引 count: 取几个值
1int[] i1 = new int[2];
2i1[0] = 1;
3i1[1] = 2;
4String str5 = new String(i1, 0, i1.length);
5System.out.println("str5= " + str5);
5.参数是StringBuffer, StringBuilder的情况.
1 StringBuffer sbuffer = new StringBuffer();
2 sbuffer.append("string");
3 sbuffer.append(" ");
4 sbuffer.append("buffer");
5 String buffer = new String(sbuffer);
6 System.out.println("buffer: " + buffer);
7
8 StringBuilder sbuilder = new StringBuilder();
9 sbuilder.append("string");
10sbuilder.append(" ");
11sbuilder.append("builder");
12String builder = new String(sbuilder);
13System.out.println("builder: " + builder);
另外String构造方法支持byte类型参数,
面试常见问题:
String a1 = "abc", 和 String a2 = new String("abc");有什么不同???
new 的方式重新开辟了内存,创建是一个全新的值和全新的引用地址.
直接定义String 方式会先在常量池中查找是否已经创建了该相等的值,若查到已有,则不开辟内存,直接创建一个引用地址指向查到的值.比如:
1 String a1 = "abc";
2 String a2 = "abc";
3 String a3 = new String("abc");
4
5 // a2创建时,发现值和a1相同,所以仅创建了引用地址指向已有的a1的值.
6 System.out.println("a1 == a2: " + a1 == a2);// true
7 System.out.println("a1.equals(a2): " + a1.equals(a2));// true: 值相等
8 // a3是用new 的方式重新开辟内存并存储与a1相等的一个独立的值.但值的引用地址是各自不同
9 System.out.println("a1 == a3: " + a1 == a3);// false
10System.out.println("a1.equals(a3): " + a1.equals(a3));// true: 值相等));// true: 值相等
二.字符串常规操作: 查找,替换,连接 分割,截取
1.查找
查找类方法简单常用,根据需求使用.
boolean contains(String argues): 判断是包含子字符串.
1String str = "Hello World !";
2System.out.println(str.contains("S"));// false
3System.out.println(str.contains("World"));// true
4System.out.println(str.contains("ell"));// true
5System.out.println(str.contains("ddd"));// false
int indexOf(String str): 查找指定字符或字符串在字符串中第一次出现地方的索引,未找到的情况返回 -1.
通过判断结果是否为-1,同样可以用作是否包含子字符串的判断.
1String str1 = "012345";
2String str2 = "23";
3String str3 = "24";
4System.out.println(str1.indexOf(str2));// 2
5System.out.println(str1.indexOf(str3));// -1
重载方法 int indexOf(String str,int index): 从index的索引处开始找,返回str第一次出现的索引下标值.
1String indexOfStr1 = "012345012345";
2String indexOfStr2 = "23";
3System.out.println(indexOfStr1.indexOf(indexOfStr2, 5));// 8
4System.out.println(indexOfStr1.indexOf(indexOfStr2, 9));// -1
int lastIndexOf(String str): 查找指定字符或字符串在字符串中最后出现的索引,无则返回-1.
1String lastIndexOfStr = "this is index of example";
2int index = lastIndexOfStr.lastIndexOf('s');
3System.out.println(index);// 6
重载: lastIndexOf(String str, int fromIndex);从指定索引处进行反向搜索.
1index = lastIndexOfStr.lastIndexOf('s', 5);
2System.out.println(index);// 3
boolean startsWith(String prefix): 如果字符串以指定的前缀开始,则返回 true;否则返回 false.
1String withStr = new String("www.runoob.com");
2System.out.println(withStr.startsWith("www"));// true
3System.out.println(withStr.startsWith("runoob"));// false
重载: boolean startsWith(String prefix, int toffset).
prefix: 前缀. toffset 字符串中开始查找的位置.
1System.out.println(withStr.startsWith("runoob", 4));// true
boolean endsWith(String suffix): 如果字符串以指定的后缀结束,则返回 true;否则返回 false.
1System.out.println(withStr.endsWith("com"));// true
char charAt(int index): 返回索引处字符.
1String codeStr = new String("abcdef");
2System.out.println(codeStr.charAt(2));// c
int codePointAt(int index): 返回指定索引处字符的Unicode编码值.
1System.out.println(codeStr.codePointAt(0));// 97
2System.out.println(codeStr.codePointAt(2));// 99
2.替换
相信很多小伙伴对replace和replaceAll这两个兄弟的印象都是一个是替换一次,一个是替换所有。
实际情况是:replace是做简单的全部字符替换,replaceAll是正则表达式替换!
但是实际的运行结果却完全相反!!!,replace把所有的|全替换掉了,replaceAll反而一个也没有替换掉!
|在正则表达式里面是特殊字符,需要转义一下才能达到与replace一样的效果;,替换后的字符串也要注意转义问题!
1String replacesrc = "aa|bb|cc";
2String replaceStr1 = replacesrc.replace("|", "");
3String replaceStr2 = replacesrc.replaceAll("|", "");
4System.out.println(replaceStr1);// aabbcc
5System.out.println(replaceStr2);// aa|bb|cc
6
7String replaceStr3 = replacesrc.replaceAll("\\|", "");
8System.out.println(replaceStr3);// aabbcc
9String replaceFirst(String regex, String replacement):
替换字符串第一个匹配给定的正则表达式的子字符串.
返回值: 成功则返回替换的字符串,失败则返回原始字符串.
1String replaceFirstStr = new String("hello runoob,I am from runoob。");
2System.out.println(replaceFirstStr.replaceFirst("runoob", "google"));
3System.out.println(replaceFirstStr.replaceFirst("(.*)runoob(.*)", "google"));
3.连接
" ",常用的+ 和 concat 方法
concat:返回连接后的字符串.
1String ljStr = "hello";
2System.out.println(ljStr + " world!");// hello world!
3
4// concat: 返回连接后的字符串.
5System.out.println(ljStr.concat(" java"));// hello java
static String join(CharSequence delimiter, CharSequence… elements)
是String 的静态方法,可直接调用.用于字符串数组各元素间插入指定的字符串.
1String[] joinStr = new String[] { "Yuan", "Mxy", "Cmy" };
2System.out.println(String.join("-", joinStr));// Yuan-Mxy-Cmy
3List names = new ArrayList<String>();
4names.add("Kite");
5names.add("Mike");
6names.add("Shon");
7System.out.println(String.join("-", names));// Kite-Mike-Shon
4.分割
split: 字符串按照指定表达式分割转成一个数组. 此处有个BUG需要注意
String[] split(String regex);
1 String splitStr1 = "a,b,c,d,e,f";
2 String[] splitArray1 = splitStr1.split(",");
3 System.out.println("splitArray1长度: " + splitArray1.length);// splitArray1长度: 6
4 for (String item : splitArray1) {
5 System.out.print(item + " ");// a b c d e f
6 }
7
8 String splitStr2 = "a,b,c,d,e,f,";// 同splitStr1不同, 末尾多了一个逗号.再来看看大小
9String[] splitArray2 = splitStr2.split(",");
10System.out.println("splitArray2长度: " + splitArray2.length);// splitArray2长度: 6
11长度仍然为6,实际应为7,最后为空的元素被默认去除了, split会默认去除末尾为空的元素!!! 算是个坑 有个重载方法,可以填坑.
重载: String[] split(String regex, int limit)
limit: 传入一个非0数字即可避免掉, 在此我们传入-1.
1String[] splitArray3 = splitStr2.split(",", -1);
2System.out.println("splitArray3长度: " + splitArray3.length);// splitArray3长度: 7
3for (String item : splitArray1) {
4 System.out.print(item);// abcdef, 结尾没有空元素,只是在数组中占了一个索引位置.
5}
5.截取
String substring(int beginIndex);
返回一个新的子字符串。该子字符串始于指定索引处的字符(包含!),一直到此字符串末尾
String substring(int beginIndex, int endIndex);
返回一个新的子字符串。该子字符串从指定的 beginIndex 处开始(包含!), endIndex:到指定的 endIndex-1处结束(不!包含).
1String substringStr1 = "abcdef";
2System.out.println(substringStr1.substring(2));// cdef
3String substringStr2 = "abcdef";
4System.out.println(substringStr2.substring(2, 4));// cd
三.正则判断方法
String类提供支持正则表达式判断的方法,省去了开发人员额外引入正则工具类.
boolean matches(String regex);
方法用于检测字符串是否匹配给定的正则表达式,同Pattern.matches(regex, str);作用完全相同,底层源码如下:
1public boolean matches(String regex) {
2 return Pattern.matches(regex, this);
3}
实例:
1String Str = new String("www.runoob.com");
2System.out.println(Str.matches("(.*)runoob(.*)"));// true
3System.out.println(Str.matches("(.*)google(.*)"));// false
4System.out.println(Str.matches("www(.*)"));// true
四.格式转换
1.转大小写 toUpperCase, 无差别,全别转换成大写.
1String toUpperStr1 = "abCdEf";
2System.out.println(toUpperStr1.toUpperCase());// ABCDEF
3// 重载 String toUpperCase(Locale locale). locale:指定本地语言属性,非特定需求无需设定
4System.out.println(toUpperStr1.toLowerCase());// abcdef
2.转字符数组 toCharArray.
1String s1 = new String("abcdef");
2char[] c = s1.toCharArray();
3System.out.println("数组c的长度为:" + c.length);// 数组c的长度为:6
4System.out.println(c);// abcdef
5System.out.println(new String(c));// abcdef
6String s2 = new String(c, 1, 2);
7System.out.println(s2);// bc
3.自定义格式转换 format
String类的format()方法用于创建格式化的字符串以及连接多个字符串对象,类似c++ 中的pringf.
可以对整数, 浮点数和日期进行格式化.
整数--|示例——将-1000显示为(1,000):
1int num = -1000;
2String str = String.format("%(,d", num);
3System.out.println(str);// (1,000)
浮点数--|对浮点数进行格式化:
1double num1 = 123.456789;
2System.out.println(String.format("浮点类型:%.2f %n", num1));// 浮点类型:123.46
3System.out.println(String.format("十六进制浮点类型:%a %n", num1));// 十六进制浮点类型:0x1.edd3c07ee0b0bp6
4System.out.println(String.format("通用浮点类型:%g ", num1));// 通用浮点类型:123.457
日期--|对日期时间进行格式化:
1Date date = new Date();
2System.out.printf(String.format("全部日期和时间信息:%tc%n", date));
3//输出: 全部日期和时间信息:星期三 二月 19 17:53:58 CST 2020
4System.out.printf(String.format("年-月-日格式:%tF%n", date));
5//输出: 年-月-日格式:2020-02-19
6System.out.printf(String.format("月/日/年格式:%tD%n", date));
7//输出: 月/日/年格式:02/19/20
8System.out.printf(String.format("HH:MM:SS PM格式(12时制):%tr%n", date));
9//输出: HH:MM:SS PM格式(12时制):05:53:58 下午
10System.out.printf(String.format("HH:MM:SS格式(24时制):%tT%n", date));
11//输出: HH:MM:SS格式(24时制):17:53:58
12System.out.printf(String.format("HH:MM格式(24时制):%tR", date));
13//输出: HH:MM格式(24时制):17:53
Ps:使用sysout 打印语句时可以省去String.format.
五.字符串转char数组,字符char数组,基本类型转String类型.
1.char[] toCharArray(): 字符串转char数组.
1String charStr1 = new String("abcdef");
2char[] charArry1 = charStr1.toCharArray();
3System.out.println(charArry1.length);// 6
4for (char c : charArry1) {
5 System.out.print(c + " ");// a b c d e f
6}
2.基本类型转String 有三种方法
1.使用包装类的toString() 方法.
2.使用String 类的静态方法String.valueOf(char数组|基本类型).
3.+上一个空字符串,得到的就是基本类型对应的字符串.
1int val1 = 10;
2String val1Str1 = Integer.toString(val1);
3String val1Str2 = String.valueOf(val1);
4String val1Str3 = val1 + "";
5System.out.println(val1Str1);// 结果: 10 (字符串类型)
6System.out.println(val1Str2);// 结果: 10 (字符串类型)
7System.out.println(val1Str3);// 结果: 10 (字符串类型)
3.valueOf(Object arg)
字符数组转String时有重载方法,可截取任意长度转换成String.
1.static String valueOf(char data[]): char数组转string.
1char[] charArray2 = { 'a', 'b', 'c', 'e', 'd', 'e' };
2String valueOfStr1 = String.valueOf(charArray2);
3System.out.println(valueOfStr1);// abcede
重载: static String valueOf(char data[], int offset, int count):
从指定索引处截取指定长度的char数组转String.
offset: 索引开始处; count: 指定长度.
1String valueOfStr2 = String.valueOf(charArray2, 2, 4);
2System.out.println(valueOfStr2);// cede
补充: 将字符串转回基本类型的方法
1.调用包装类的parseXXX静态方法.
2.调用包装类的valueOf()方法转换为基本类型的包装类,会自动拆解转换.
1String strInt1 = "8";
2int si1 = Integer.parseInt(strInt1);
3int si2 = Integer.valueOf(strInt1);
扫码关注微信公众号-java源码栈, 及时充电!