package com.xt.java1;
import org.junit.Test;
/**
* ClassName: StringTest
* Description:
* date: 2022/4/16 10:51
*
* @author tongy
* @since JDK 1.8
*/
public class StringTest {
/*
String:字符串,使用一对""引起来表示。
1.String声明为final的,不可被继承
2.String实现了Serializable接口:表示字符串是支持序列化的。
实现了Comparable接口:表示String可以比较大小
3.String内部定义了final char[] value用于存储字符串数据
4.String:代表不可变的字符串序列。简称:不可变性。
体现:1.当对字符串重新赋值时,需要重写指定内存区域赋值,不能使用原有的value进行赋值
2.当对现有的字符串进行连接操作时,也需要重新给指定内存区域赋值,不能使用原有的value进行赋值
3.当调用String的replace()修改指定字符或字符串时,也必须重新给指定内存区域赋值,不能使用原有的value进行赋值
5.通过字面量的方式(区别于new())给一个字符串赋值,此时的字符串值声明在字符串常量池中。
6.字符串常量池中是不会存储相同内容的字符串的。
*/
@Test
public void Test1(){
String s1="abc"; //自面量的定义方式
String s2="abc";
// s1="hello";
System.out.println(s1 == s2); //比较s1、s2的地址值
System.out.println(s1);
System.out.println(s2);
System.out.println("*****************");
String s3="abc";
s3+="def";
System.out.println(s3); //abcdef
System.out.println("*****************");
String s4=s2.replace('a','m');
System.out.println(s4);
}
/*
String的实例化方式:
方式一:通过字面量定义的方式
方式二:new+构造器的方式
面试题:String s=new String("abc")方式创建对象,在内存中创建了几个对象
两个:一个是堆空间中new结构,另一个是char[]对应的常量池中的数据:”abc“
*/
@Test
public void Test2(){
//此时的s1、s2数据javaEE声明在方法区的字符串常量池中。
String s1="JavaEE";
String s2="JavaEE";
//new+构造器的方式,此时s3、s4保存的地址值,是数据在堆空间中开辟空间以后对应的地址值
String s3=new String("JavaEE");
String s4=new String("JavaEE");
System.out.println(s1 == s2); //true
System.out.println(s3 == s4); //false
System.out.println("***************");
Person p1=new Person("Tom",12);
Person p2=new Person("Tom",12);
System.out.println(p1.name == p2.name); //true
System.out.println(p1.name.equals(p2.name)); //true
}
/**
* 常量与常量的拼接结果在常量池,且常量池中不会出现相同内容的常量
* 只要其中有一个是变量,结果就在堆中
* 如果拼接的结果调用intern()方法,返回值就在常量池中
*/
@Test
public void Test3(){
String s1="JavaEE";
String s2="Hadoop";
String s3="JavaEEHadoop";
String s4="JavaEE"+"Hadoop";
//有变量名参与,此时数据都不是在常量池中,相当于new,s5存储的是堆的地址值
String s5=s1+"Hadoop";
String s6=s1+s2;
System.out.println(s4 == s3); //true
System.out.println(s4 == s5); //false
System.out.println(s4 == s6); //false
System.out.println(s5 == s6); //false
System.out.println(s3 == s5); //false
System.out.println(s3 == s6); //false
String s7=s5.intern(); //返回值得到的s8使用的常量池中已经存在的”JavaEEHadoop“
System.out.println(s3 == s7);//true
}
}
package com.xt.java1;
/**
* ClassName: StringTest1
* Description:
* date: 2022/4/16 17:08
*
* @author tongy
* @since JDK 1.8
*/
public class StringTest1 {
String str=new String("good");
char[] c={'t','e','s','t'};
//String 不可变性(引用类型)
public void exchange(String str,char[] ch){
str="test ok";
ch[0]='b';
}
public static void main(String[] args) {
StringTest1 st=new StringTest1();
st.exchange(st.str,st.c);
System.out.print(st.str); //good
System.out.print(st.c); //best
}
}
package com.xt.java1;
import org.junit.Test;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
/**
* ClassName: StringTest2
* Description:涉及到String类与其他结构之间的转换
* date: 2022/4/17 11:14
*
* @author tongy
* @since JDK 1.8
*/
public class StringTest2 {
/*
复习:
String 与基本类型、包装类之间的转换
String -->基本类型、包装类-->调用包装类的静态方法 parseXxx(String str)
基本类型、包装类-->String :调用String重载的valueOf(xxx)
*/
@Test
public void test1(){
String str1="123";
int num = Integer.parseInt(str1);
System.out.println(num);
System.out.println(String.valueOf(num));
}
/*
String、char[]之间的转换
String-->char[] 调用String的toCharArray()
char[]-->String 调用String的构造器
*/
@Test
public void test2(){
String str1="abc123";
char[] c1 = str1.toCharArray();
for (int i = 0; i < c1.length; i++) {
System.out.println(c1[i]);
}
char[] c2=new char[]{'h','e','l','l','o'};
String str2 = new String(c2);
System.out.println(str2);
}
/*
String 与 byte[]之间的转换
编码:String --> byte[]:调用String的getBytes()
解码:byte[]--String:调用String的构造器
编码:字符串-->字节(看得懂-->看不懂的)
解码:编码的逆过程
说明:解码时,要求解码使用的字符集必须与编码时使用的字符集一致,否则会出现乱码
*/
@Test
public void test3() throws UnsupportedEncodingException {
String str1="abc123中国";
byte[] b1 = str1.getBytes(); //使用默认的字符集进行编码
byte[] gbks = str1.getBytes("gbk"); //使用gbk字符集进行编码
System.out.println(Arrays.toString(b1));
System.out.println(Arrays.toString(gbks));
String s1 = new String(b1); //使用默认的字符集进行解码
System.out.println(s1);
String s2 = new String(gbks); //默认是utf-8进行解码,而gbks是由gbk编码的,故出现乱码
System.out.println(s2);
String s3 = new String(gbks, "gbk");//gbk进行解码
System.out.println(s3);
}
}
String类的常用方法
package com.xt.java1;
import org.junit.Test;
import java.util.Locale;
/**
* ClassName: StringMethodTest
* Description:String的常用方法
* date: 2022/4/16 17:32
*
* @author tongy
* @since JDK 1.8
*/
public class StringMethodTest {
@Test
public void Test1(){
String s1="Helloworld";
//返回字符串的长度
System.out.println(s1.length());
//返回字符串指定位置的字符
System.out.println(s1.charAt(2));
//将字符串全部改为小写
System.out.println(s1.toLowerCase(Locale.ROOT)); //而s1是不可变的,仍为原来的字符串
//去掉原来字符串首部和尾部的一到多个空格
String s2=" Hello Worl d ";
String s3=s2.trim();
System.out.println(s3); //Hello Worl d
//忽略大小写的情况下对比
String s4="helloworld";
System.out.println(s4.equalsIgnoreCase(s1)); //true
//字符串连接
String s5="abc";
String s6 = s5.concat("def");
System.out.println(s6);
//涉及到字符串排序。
String s7=new String("abe");
System.out.println(s6.compareTo(s7)); //-2 与字符串声明的方式无关,与字符串的内容有关。
//字符串截取子串(左闭右开)
String s8="从前有座山";
String s9=s8.substring(2,5);
System.out.println(s9); //有座山
//endsWith(str) 判断字符串是否以str结束.startsWith(str)判断字符串是否以str开始
//startsWith(str,int toffset)判断字符串从指定索引开始的子字符串是否以指定前缀开始
String s01="abcdefg";
System.out.println(s01.endsWith("efg")); //true
System.out.println(s01.startsWith("Abc")); //false
System.out.println(s01.startsWith("defg",3)); //true
//判断某个字符串是否含有子串contains(str)
System.out.println(s01.contains("de")); //true
//indexOf(str) 返回某个子串在原串的索引,若没有,则返回-1
//indexOf(str,int index) 从指定的位置开始,找str,返回索引位置,若没找到,返回-1
//lastIndexOf(str) 从后往前找str
//lastIndexOf(str,int index) 从index位置从右往左搜索
System.out.println(s01.indexOf("def"));
System.out.println(s01.indexOf("bc",3)); //-1
System.out.println(s01.indexOf("bc",1)); //1
String s02="hellorworld";
System.out.println(s02.lastIndexOf("or")); //7
System.out.println(s02.lastIndexOf("or",6)); //4
//什么情况下:indexOf(str)和lastIndexOf(str)返回值相同?
//情况一:只存在一个str的情况。情况二:不存在str
}
/*
替换
String replace(char oldChar,char newChar) 用新字符替换所有旧字符
String replace(CharSequence target,CharSequence replacement)新的字符串替换所有旧的字符串
String replaceAll(String regex,String replacement)使用给定的replacement替换此字符串所有匹配给定的正则表达式的子字符串
String replaceFirst(String regex,String replacement)使用给定的replacement替换此字符串第一个匹配给定的正则表达式的子字符串
匹配
boolean matches(String regex)告知此字符串是否匹配给定的正则表达式
拆分
String[] split(String regex) 根据匹配给定的正则表达式来拆分此字符串
String[] split(String regex,int limit) 根据匹配给定的正则表达式来拆分此字符串,
*/
@Test
public void Test2(){
String str1="我思故我在思";
System.out.println(str1.replace('思','在'));
System.out.println(str1);
String str2="123hello456world78java90";
System.out.println(str2.replaceAll("\\d+",",").replaceAll("^,|,$",""));
String str3="12345";
//判断str4是否全为数字
boolean str4 = str3.matches("\\d+");
System.out.println(str4);
//匹配电话号码
String str5="0210-88164061";
System.out.println(str5.matches("0210-\\d{7,8}"));
String str6="xu|wen|qiang";
String[] str6_1 = str6.split("\\|");
for (int i = 0; i < str6_1.length; i++) {
System.out.println(str6_1[i]);
}
}
}