字符串相关的类
String的特性
-
test1
-
String类:代表字符串。Java 程序中的所有字符串字面值(如 “abc” )都作为此类的实例实现
-
String是一个final类,代表不可变的字符序列
-
字符串是常量,用双引号引起来表示。它们的值在创建之后不能更改。
-
String对象的字符内容是存储在一个字符数组value[ ]中的
字符串相关的类:string
- test2
字符串对象是如何存储的
-
test3
-
package com.atguigu.java; import org.junit.Test; /** * String的使用 * * @Author damao * @Date 2022/2/2 20:07 * @Version 1.0 */ public class StringTest { /* 结论: 1.常量与常量的拼接结果在常量池。且常量池中不会存在相同内容的常量 2.只要其中有一个是变量,结果就在堆中 3.如果拼接的结果调用intern()方法,返回值就在常量池中 */ @Test public void test4(){ String s1 = "javaEEhadoop"; String s2 = "javEE"; String s3 = s2 + "hadoop"; System.out.println(s1 == s3);//false final String s4 = "javaEE";//s4:常量 String s5 = s4 + "hadoop"; System.out.println(s1 == s5);//true } @Test public void test3(){ String s1 = "javaEE"; String s2 = "hadoop"; String s3 = "javaEEhadoop"; String s4 = "javaEE" + "hadoop"; String s5 = s1 + "hadoop"; String s6 = "javaEE" + s2; String s7 = s1 + s2; System.out.println(s3 == s4);//true System.out.println(s3 == s5);//false System.out.println(s3 == s6);//false System.out.println(s3 == s7);//false System.out.println(s5 == s6);//false System.out.println(s5 == s7);//false System.out.println(s6 == s7);//false String s8 = s5.intern();//返回得到的s8使用的常量池中已经存在的"javaEEhadoop" System.out.println(s3 == s8);//true } /* String的实例化方式: 方式一:通过字面量定义的方式 方式二:通过new + 构造器的方式 面试题:String s = new String("abc");方式创建对象,在内存中创建了几个对象?两个 1.一个是对空间中new结构 2.另一个是char[]对应的常量池中的数据:“abc” 3.字符串常量存储在字符串常量池,目的是共享 4.字符串非常量对象存储在堆中 */ @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(s1 == s3);//false System.out.println(s1 == s4);//false 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.equals(p2.name));//true System.out.println(p1.name == p2.name);//true p1.name = "Jerry"; System.out.println(p2.name);//Tom } /* 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);//hello System.out.println(s2);//abc System.out.println("=============="); String s3 = "abc"; s3 += "def"; System.out.println(s3);//abcdef System.out.println(s2);//abc System.out.println("=============="); String s4 = "abc"; String s5 = s4.replace('a','m'); System.out.println(s4);//abc System.out.println(s5);//mbc } }
-
package com.atguigu.java; /** * @Author damao * @Date 2022/2/9 16:39 * @Version 1.0 */ public class Person { String name; int age; public Person(String name, int age) { this.name = name; this.age = age; } public Person() { } }
String使用陷阱
- String s1 = “a”;
- 说明:在字符串常量池中创建了一个字面量为"a"的字符串
- s1 = s1 + “b”;
- 说明:实际上原来的“a”字符串对象已经丢弃了,现在在堆空间中产生了一个字符串s1+“b”(也就是"ab")。如果多次执行这些改变串内容的操作,会导致大量副本字符串对象存留在内存中,降低效率。如果这样的操作放到循环中,会极大影响程序的性能
- String s2 = “ab”;
- 说明:直接在字符串常量池中创建一个字面量为"ab"的字符串
- String s3 = “a” + “b”;
- 说明:s3指向字符串常量池中已经创建的"ab"的字符串
- String s4 = s1.intern();
- 说明:堆空间的s1对象在调用intern()之后,会将常量池中已经存在的"ab"字符串赋值给s4
面试题
-
package com.atguigu.exer; /** * 一道面试题 * @Author damao * @Date 2022/2/9 20:40 * @Version 1.0 */ public class StringTest { String str = new String("good"); char[] ch = { 't', 'e', 's', 't' }; public void change(String str, char ch[]) { str = "test ok"; ch[0] = 'b'; } public static void main(String[] args) { StringTest ex = new StringTest(); ex.change(ex.str, ex.ch); System.out.println(ex.str);//good System.out.println(ex.ch);//best } }
String常用方法1
-
int length():返回字符串的长度: return value.length
-
char charAt(int index): 返回某索引处的字符return value[index]
-
boolean isEmpty():判断是否是空字符串:return value.length == 0
-
String toLowerCase():使用默认语言环境,将 String 中的所有字符转换为小写
-
String toUpperCase():使用默认语言环境,将 String 中的所有字符转换为大写
-
String trim():返回字符串的副本,忽略前导空白和尾部空白
-
boolean equals(Object obj):比较字符串的内容是否相同
-
boolean equalsIgnoreCase(String anotherString):与equals方法类似,忽略大小写
-
String concat(String str):将指定字符串连接到此字符串的结尾。 等价于用“+”
-
int compareTo(String anotherString):比较两个字符串的大小
-
String substring(int beginIndex):返回一个新的字符串,它是此字符串的从beginIndex开始截取到最后的一个子字符串
-
String substring(int beginIndex, int endIndex) :返回一个新字符串,它是此字符串从beginIndex开始截取到endIndex(不包含)的一个子字符串
-
package com.atguigu.java; import org.junit.Test; /** * @Author damao * @Date 2022/2/10 8:18 * @Version 1.0 */ public class StringMethodTest { /* int length():返回字符串的长度: return value.length char charAt(int index): 返回某索引处的字符return value[index] boolean isEmpty():判断是否是空字符串:return value.length == 0 String toLowerCase():使用默认语言环境,将 String 中的所有字符转换为小写 String toUpperCase():使用默认语言环境,将 String 中的所有字符转换为大写 String trim():返回字符串的副本,忽略前导空白和尾部空白 boolean equals(Object obj):比较字符串的内容是否相同 boolean equalsIgnoreCase(String anotherString):与equals方法类似,忽略大小写 String concat(String str):将指定字符串连接到此字符串的结尾。 等价于用“+” int compareTo(String anotherString):比较两个字符串的大小 String substring(int beginIndex):返回一个新的字符串,它是此字符串的从beginIndex开始截取到最后的一个子字符串 String substring(int beginIndex, int endIndex) :返回一个新字符串,它是此字符串从beginIndex开始截取到endIndex(不包含)的一个子字符串 */ @Test public void test2(){ String s1 = "HelloWorld"; String s2 = "helloworld"; System.out.println(s1.equals(s2));//false System.out.println(s1.equalsIgnoreCase(s2));//true String s3 = "abc"; String s4 = s3.concat("def"); System.out.println(s4);//abcdef String s5 = "abc"; String s6 = new String("abe"); System.out.println(s5.compareTo(s6));//涉及到字符串排序 String s7 = "江西九命猫大喵"; String s8 = s7.substring(2); System.out.println(s7);//江西九命猫大喵 System.out.println(s8);//九命猫大喵 String s9 = s7.substring(2,5); System.out.println(s9);//九命猫 } @Test public void test1(){ String s1 = "HelloWorld"; System.out.println(s1.length());//10 System.out.println(s1.charAt(0));//h System.out.println(s1.charAt(9));//d // System.out.println(s1.charAt(10));//超出范围 // s1 = ""; System.out.println(s1.isEmpty());//true String s2 = s1.toLowerCase(); System.out.println(s1);//HelloWorld s1不可变,仍然为原来的字符串 System.out.println(s2);//helloworld 改成小写以后的字符串 String s3 = " he llo world "; String s4 = s3.trim(); System.out.println("----" + s3 + "----");//---- he llo world ---- System.out.println("----" + s4 + "----");//----he llo world---- } }
String常用方法2
-
boolean endsWith(String suffix):测试此字符串是否以指定的后缀结束
-
boolean startsWith(String prefix):测试此字符串是否以指定的前缀开始
-
boolean startsWith(String prefix, int toffset):测试此字符串从指定索引开始的子字符串是否以指定前缀开始
-
boolean contains(CharSequence s):当且仅当此字符串包含指定的 char 值序列时,返回 true
-
int indexOf(String str):返回指定子字符串在此字符串中第一次出现处的索引
-
int indexOf(String str, int fromIndex):返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始
-
int lastIndexOf(String str):返回指定子字符串在此字符串中最右边出现处的索引
-
int lastIndexOf(String str, int fromIndex):返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索
-
注:indexOf和lastIndexOf方法如果未找到都是返回-1
-
package com.atguigu.java; import org.junit.Test; /** * @Author damao * @Date 2022/2/11 19:51 * @Version 1.0 */ public class StringMethodTest2 { /* boolean endsWith(String suffix):测试此字符串是否以指定的后缀结束 boolean startsWith(String prefix):测试此字符串是否以指定的前缀开始 boolean startsWith(String prefix, int toffset):测试此字符串从指定索引开始的子字符串是否以指定前缀开始 boolean contains(CharSequence s):当且仅当此字符串包含指定的 char 值序列时,返回 true int indexOf(String str):返回指定子字符串在此字符串中第一次出现处的索引 int indexOf(String str, int fromIndex):返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始 int lastIndexOf(String str):返回指定子字符串在此字符串中最右边出现处的索引 int lastIndexOf(String str, int fromIndex):返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索 注:indexOf和lastIndexOf方法如果未找到都是返回-1 */ @Test public void test3(){ String str1 = "helloworld"; boolean b1 = str1.endsWith("ld"); System.out.println(b1);//true boolean b2 = str1.startsWith("He"); System.out.println(b2);//false boolean b3 = str1.startsWith("ll",2); System.out.println(b3);//true String str2 = "wor"; System.out.println(str1.contains(str2));//true System.out.println(str1.indexOf("lo"));//3 System.out.println(str1.indexOf("lol"));//-1 System.out.println(str1.indexOf("lo",5));//false String str3 = "hellorworld"; System.out.println(str3.lastIndexOf("or"));//7 System.out.println(str3.lastIndexOf("or",6));//4 //什么情况下,indexof(str)和lastIndexof(str)返回值相同? //情况一:存在唯一的一个str //情况二:不存在str } }
String常用方法3
-
String replace(char oldChar, char newChar):返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的
-
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):根据匹配给定的正则表达式来拆分此字符串,最多不超过limit个,如果超过了,剩下的全部都放到最后一个元素中
-
package com.atguigu.java; import org.junit.Test; /** * @Author damao * @Date 2022/2/11 20:44 * @Version 1.0 */ public class StringMethodTest3 { /* 替换: String replace(char oldChar, char newChar):返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的 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):根据匹配给定的正则表达式来拆分此字符串,最多不超过limit个,如果超过了,剩下的全部都放到最后一个元素中 */ @Test public void test4(){ //替换 String str1 = "江西九命猫小宇"; String str2 = str1.replace('西', '东'); System.out.println(str1);//江西九命猫小宇 System.out.println(str2);//江东九命猫小宇 String str3 = str1.replace("江西", "浙江"); System.out.println(str3);//浙江九命猫小宇 System.out.println("================="); String str4 = "12hello34world5java7891mysql456"; //把字符串中的数字替换成,,如果结果中开头和结尾有,的话去掉 String string = str4.replaceAll("\\d+", ",").replaceAll("^,|,$", ""); System.out.println(string);//hello,world,java,mysql //匹配 String str5 = "12345"; //判断str字符串中是否全部有数字组成,即有1-n个数字组成 boolean matches = str5.matches("\\d+"); System.out.println(matches);//true String tel = "0571-4534289"; //判断这是否是一个杭州的固定电话 boolean result = tel.matches("0571-\\d{7,8}"); System.out.println(result);//true System.out.println("-------------"); //切割 String str6 = "hello|world|java"; String[] strs = str6.split("\\|"); for (int i = 0; i < strs.length; i++) { System.out.println(strs[i]); } System.out.println(); String str7 = "hello.world.java"; String[] strs7 = str7.split("\\."); for (int i = 0; i < strs7.length; i++) { System.out.println(strs7[i]); } } }
复习
-
字符串 -> 基本数据类型、包装类
-
基本数据类型、包装类 -> 字符串
-
字符数组 -> 字符串
-
字符串 -> 字符数组
-
字节数组 -> 字符串
-
字符串 -> 字节数组
-
package com.atguigu.java; import org.junit.Test; import java.io.UnsupportedEncodingException; import java.util.Arrays; /** * 涉及到String类与其他结构之间的转换 * * @Author damao * @Date 2022/2/12 7:49 * @Version 1.0 */ public class StringTest1 { /* 复习: String与基本数据类型、包装类之间的转换 String --> 基本数据类型、包装类:调用包装类的静态方法:parseXxx(str) 基本数据类型、包装类 --> String:调用String重载的valueOf(xxx) */ @Test public void test1(){ String str1 = "123"; // int num = (int)str1;//错误的 int num = Integer.parseInt(str1); String str2 = String.valueOf(num);//"123" String str3 = num + ""; System.out.println(str1 == str2);//false } /* String 与 char[] 之间的转换 String --> char[]:调用String的toCharArray() char[] --> String:调用String的构造器 */ @Test public void test2(){ String str1 = "abc123";//题目:a21cb3 char[] charArray = str1.toCharArray(); for (int i = 0; i < charArray.length; i++) { System.out.println(charArray[i]); } char[] arr = new char[]{'h','e','l','l','o'}; String str2 = new String(arr); System.out.println(str2); } /* String 与 byte[] 之间的转换 编码:String --> byte[]:调用String的getBytes() 解码:byte[] --> String:调用String构造器 编码:字符串 --> 字节(看得懂 --> 看不懂的二进制数据) 解码:编码的逆过程,字节 --> 字符串(看不懂的二进制数据 --> 看得懂) 说明:解码时,要求解码使用的字符集和编码时使用的一致,否则会出现乱码 */ @Test public void test3() throws UnsupportedEncodingException { String str1 = "abc123"; byte[] bytes = str1.getBytes();//使用默认的字符集,进行转换 System.out.println(Arrays.toString(bytes)); byte[] gbks = str1.getBytes("gbk");//使用gbk编码集进行编码 System.out.println(Arrays.toString(gbks)); System.out.println("*********************"); String str2 = new String(bytes);//使用默认的字符集,进行解码 System.out.println(str2); String str3 = new String(gbks); System.out.println(str3);//出现乱码,原因:编码集和解码集不一致 String str4 = new String(gbks,"gbk"); System.out.println(str4);//没有出现乱码,编码集和解码集一致 } }
StringBuffer类
- java.lang.StringBuffer代表可变的字符序列,JDK1.0中声明,可以对字符串内容进行增删,此时不会产生新的对象。
- 很多方法与String相同。
- 作为参数传递时,方法内部可以改变值
- StringBuffer类不同于String,其对象必须使用构造器生成。有三个构造器:
- StringBuffer():初始容量为16的字符串缓冲区
- StringBuffer(int size):构造指定容量的字符串缓冲区
- StringBuffer(String str):将内容初始化为指定字符串内容
StringBuffer类的常用方法
- StringBuffer append(xxx):提供了很多的append()方法,用于进行字符串拼接
- StringBuffer delete(int start,int end):删除指定位置的内容
- StringBuffer replace(int start, int end, String str):把[start,end)位置替换为str
- StringBuffer insert(int offset, xxx):在指定位置插入xxx
- StringBuffer reverse() :把当前字符序列逆转
package com.atguigu.java;
import org.junit.Test;
/**
* 关于StringBuffer和StringBuilder的使用
*
* @Author damao
* @Date 2022/2/15 8:04
* @Version 1.0
*/
public class StringBufferBuilderTest {
/*
对比String、StringBuffer、StringBuilder三者的效率:
从高到低排列:StringBuilder > StringBuffer > String
*/
@Test
public void test3(){
//初始设置
long startTime = 0L;
long endTime = 0L;
String text = "";
StringBuffer buffer = new StringBuffer("");
StringBuilder builder = new StringBuilder("");
//开始对比
startTime = System.currentTimeMillis();
for (int i = 0; i < 20000; i++) {
buffer.append(String.valueOf(i));
}
endTime = System.currentTimeMillis();
System.out.println("StringBuffer的执行时间:" + (endTime - startTime));
startTime = System.currentTimeMillis();
for (int i = 0; i < 20000; i++) {
builder.append(String.valueOf(i));
}
endTime = System.currentTimeMillis();
System.out.println("StringBuilder的执行时间:" + (endTime - startTime));
startTime = System.currentTimeMillis();
for (int i = 0; i < 20000; i++) {
text = text + i; }
endTime = System.currentTimeMillis();
System.out.println("String的执行时间:" + (endTime - startTime));
}
/*
StringBuffer append(xxx):提供了很多的append()方法,用于进行字符串拼接
StringBuffer delete(int start,int end):删除指定位置的内容
StringBuffer replace(int start, int end, String str):把[start,end)位置替换为str
StringBuffer insert(int offset, xxx):在指定位置插入xxx
StringBuffer reverse() :把当前字符序列逆转
public int indexOf(String str)
public String substring(int start,int end):返回一个从start开始到end索引结束的左闭右开区间的子字符串
public int length()
public char charAt(int n )
public void setCharAt(int n ,char ch)
总结:
增:append(xxx)
删:delete(int start,int end)
改:setCharAt(int n,char ch) 修改一个字符 / replace(int start,int end,String str)替换成一个字符串
查:charAt(int n )
插:insert(int offset, xxx)
长度:length()
遍历:for() + charAt() / toString()
*/
@Test
public void test2(){
StringBuffer s1 = new StringBuffer("abc");
s1.append(1);
s1.append('1');
System.out.println(s1);//abc11
// s1.delete(2,4);//删除 ab1
// s1.replace(2,4,"hello");//替换 abhello1
// s1.insert(2,false);//插入 abfalsec11
// s1.reverse();//逆序 11cba
String s2 = s1.substring(1, 3);
System.out.println(s1);
System.out.println(s1.length());//10
System.out.println(s2);//bc
}
/*
String、StringBuffer、StringBuilder三者的异同?
String:不可变的字符序列;底层使用char[]存储
StringBuffer:可变的字符序列;线程安全的,效率低;底层使用char[]存储
StringBuilder:可变的字符序列;jdk5.0新增的,线程不安全的,效率高,底层使用char[]存储
源码分析:
String str = new String();//char value = new char[0];
String str = new String("abc");//char value = new char[]{'a','b','c'};
StringBuffer sb1 = new StringBuffer();//char value = new char[16];底层创建了一个长度是16的数组
System.out.println(sb1.length());//
sb1.append('a');//value[0] = 'a';
sb1.append('b');//value[1] = 'b';
StringBuffer sb2 = new StringBuffer("abc");//char[] value = new char["abc".length() + 16];
//问题1.System.out.println(sb2.length());//3
//问题2.扩容问题:如果要添加的数据底层数组存不下了,那就要扩容底层的数组
默认情况下,扩容为原来容量的2倍 + 2,同时将原有数组中的元素复制到新的数组中
指导意义:开发中建议大家使用:StringBuffer(int capacity) 或 StringBuilder(int capacity)
*/
@Test
public void test1(){
StringBuffer sb1 = new StringBuffer("abc");
sb1.setCharAt(0,'m');
System.out.println(sb1);//mbc
StringBuffer sb2 = new StringBuffer();
System.out.println(sb2.length());//0
}
}
StringBuilder类
- StringBuilder和StringBuffer非常类似,均代表可变的字符序列,而且提供相关功能的方法也一样
- 面试题:对比String、StringBuffer、StringBuilder
- String(JDK1.0):不可变字符序列
- StringBuffer(JDK1.0):可变字符序列、效率低、线程安全
- StringBuilder(JDK 5.0):可变字符序列、效率高、线程不安全
- 注意:作为参数传递的话,方法内部String不会改变其值,StringBuffer和StringBuilder会改变其值。
常见算法题
-
将一个字符串进行反转。将字符串中指定部分进行反转。比如“abcdefg”反转为”abfedcg”
-
package com.atguigu.exer; import org.junit.Test; /** * @Author damao * @Date 2022/3/4 11:19 * @Version 1.0 */ public class StringDemo { /* 将一个字符串进行反转。将字符串中指定部分进行反转。比如“abcdefg”反转为”abfedcg” 方式一:转换为char[] */ public String reverse(String str,int startIndex,int endIndex) { if (str != null && str.length() != 0) { char[] arr = str.toCharArray(); for (int x = startIndex,y = endIndex;x < y;x++, y--){ char temp = arr[x]; arr[x] = arr[y]; arr[y] = temp; } return new String(arr); } return null; } //方式二:使用String拼接 public String reverse1(String str,int startIndex,int endIndex){ if (str != null){ //第1部分 String reverseStr = str.substring(0,startIndex); //第2部分 for (int i = endIndex;i >= startIndex;i--){ reverseStr += str.charAt(i); } //第3部分 reverseStr += str.substring(endIndex + 1); return reverseStr; } return null; } //方式三:使用StringBuilder/StringBuffer替换String public String reverse2(String str,int startIndex,int endIndex){ if (str != null){ StringBuilder builder = new StringBuilder(str.length()); //第1部分 builder.append(str.substring(0,startIndex)); //第2部分 for (int i = endIndex;i >= startIndex;i--){ builder.append(str.charAt(i)); } //第3部分 builder.append(str.substring(endIndex + 1)); return builder.toString(); } return null; } @Test public void testReverse(){ String str = "abcdefg"; String reverse = reverse2(str, 2, 5); System.out.println(reverse);//abfedcg } }
-
获取一个字符串在另一个字符串中出现的次数。比如:获取“ ab”在 “abkkcadkabkebfkabkskab” 中出现的次数
-
package com.atguigu.exer; import org.junit.Test; /** * @Author damao * @Date 2022/3/4 12:13 * @Version 1.0 */ public class StringDemo1 { /* 获取一个字符串在另一个字符串中出现的次数。比如:获取“ ab”在 “abkkcadkabkebfkaabkskab” 中出现的次数 */ /** * 获取subStr在mainStr中出现的次数 */ public int getCount(String mainStr,String subStr){ int mainLength = mainStr.length(); int subLength = subStr.length(); int count = 0; int index = 0; if (mainLength >= subLength){ //方式一 // while ((index = mainStr.indexOf(subStr)) != -1){ // count++; // mainStr = mainStr.substring(index + subStr.length()); // } //方式二:对方式一的改进 while ((index = mainStr.indexOf(subStr,index)) != -1){ count++; index += subLength; } return count; }else { return 0; } } @Test public void testGetCount(){ String mainStr = "abkkcadkabkebfkaabkskab"; String subStr = "ab"; int count = getCount(mainStr, subStr); System.out.println(count); } }
-
获取两个字符串中最大相同子串。比如:str1 = "abcwerthelloyuiodef“;str2 = "cvhellobnm"提示:将短的那个串进行长度依次递减的子串与较长的串比较。
-
package com.atguigu.exer; import org.junit.Test; import java.util.Arrays; /** * @Author damao * @Date 2022/3/23 13:46 * @Version 1.0 */ public class StringDemo2 { /* 获取两个字符串中最大相同子串。比如: str1 = "abcwerthelloyuiodefabcdef“;str2 = "cvhellobnm" 提示:将短的那个串进行长度依次递减的子串与较长的串比较 */ //前提:两个子串中只有一个最大相同子串 public String getMaxSameString(String str1, String str2) { if (str1 != null && str2 != null) { String maxStr = (str1.length() >= str2.length()) ? str1 : str2; String minStr = (str1.length() < str2.length()) ? str1 : str2; int length = minStr.length(); for (int i = 0; i < length; i++) { for (int x = 0, y = length - i; y <= length; x++, y++) { String subStr = minStr.substring(x, y); if (maxStr.contains(subStr)) { return subStr; } } } } return null; } // 如果存在多个长度相同的最大相同子串 // 此时先返回String[],后面可以用集合中的ArrayList替换,较方便 public String[] getMaxSameString1(String str1, String str2) { if (str1 != null && str2 != null) { StringBuffer sBuffer = new StringBuffer(); String maxString = (str1.length() > str2.length()) ? str1 : str2; String minString = (str1.length() > str2.length()) ? str2 : str1; int len = minString.length(); for (int i = 0; i < len; i++) { for (int x = 0, y = len - i; y <= len; x++, y++) { String subString = minString.substring(x, y); if (maxString.contains(subString)) { sBuffer.append(subString + ","); } } // System.out.println(sBuffer); if (sBuffer.length() != 0) { break; } } String[] split = sBuffer.toString().replaceAll(",$", "").split("\\,"); return split; } return null; } @Test public void testGetMaxSameString() { String str1 = "abcwerthello1yuiodefabcdef"; String str2 = "cvhello1bnmabcdef"; String[] maxSameStrings = getMaxSameString1(str1, str2); System.out.println(Arrays.toString(maxSameStrings)); } }