一、API文档使用
- JDK 版本:1.8.0_231
- Java SE API Documentation:jdk-9_汉化版.CHM
1.1 API概述
- 什么是API
API (**Application Programming Interface**
) :应用程序编程接口 - Java中的API
指的就是 JDK 中提供的各种功能的 Java类、抽象类、接口,这些类将底层的实现封装了起来,我们不需要关心这些类是如何实现的,只需要学习这些类如何使用即可,我们可以通过API文档(说明书)来学习这些类如何使用。
如何使用API帮助文档 :
- 打开帮助文档
- 找到索引选项卡中的输入框
- 你要找什么?在输入框里输入你要找的类名,然后回车
- 在输入框中输入Random
- 看类在哪个包下
看类的描述
看构造方法:了解这个类有几种方式创建对象
看成员方法:了解这个类有哪些功能以及使用方法
1.2 键盘录入字符串
Scanner类 :
next() : 遇到了空格, 就不再录入数据了 , 结束标记: 空格, tab键
nextLine() : 可以将数据完整的接收过来 , 结束标记: 回车换行符
ctrl + alt + v : 快速生成方法的返回值
代码实现 :
package com.lhl.api;
import java.util.Scanner;
public class Demo1Scanner {
/*
next() : 遇到了空格, 就不再录入数据了
结束标记: 空格, tab键
nextLine() : 可以将数据完整的接收过来
结束标记: 回车换行符
*/
public static void main(String[] args) {
// 1. 创建Scanner对象
Scanner sc = new Scanner(System.in);
System.out.println("请输入:");
// 2. 调用nextLine方法接收字符串
// ctrl + alt + v : 快速生成方法的返回值
String s = sc.nextLine();
System.out.println(s);
}
}
二、String类
2.1 String概述
- String 类在 java.lang 包下,使用的时候不需要导包
- String 类是一个
** final 类**
(太监类),代表**不可变的字符序列**
- String 类:代表字符串,Java 程序中的所有字符串文字(例如“abc”)都被实现为此类的实例,也就是说,Java 程序中所有的双引号字符串,都是 String 类的对象
- 字符串是常量,用双引号(
""
)引起来表示。它们的值在创建之后不能更改,要更改只是对象的替换 String 对象的字符串内容是存储在一个字符数组
value[]
中的。public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
/** Cache the hash code for the string */
private int hash; // Default to 0
...
}
代码实现
package com.lhl.string;
public class Demo1String {
/*
Java程序中, 所有的双引号字符串, 都是String这个类的对象
字符串是常量;它们的值在创建之后不能更改,要更改只是对象的替换
*/
public static void main(String[] args) {
String s1="123";
String s2="123";
s2 = "hello";
}
}
2.2 String 特点
- ① 字符串 String 类型本身是 final 修饰的,意味着我们不能继承 String。
② 字符串的对象也是不可变对象,意味着一旦进行修改,就会产生新的对象。
注意:如果程序中涉及到了大量的字符串的修改操作,那么此时的内存消耗比较高,可能需要考虑使用 StringBuilder 或 StringBuffer 的可变字符序列。
③ String 对象内部是用字符数组保存的。
JDK 9 之前是用 char[] 数组保存的,JDK 9 之后时用 byte[] 数组保存的。
④ String 类中的 char[] values 数组也是用 final 修饰的,意味着这个数组不可变,又因为是用 private 修饰的,意味着外界不能直接操作它。String 类提供的所有方法都是用新对象来表示修改后的内容的,保证了 String 对象的不可变。
- ⑤ 因为 String 对象设计为不可变,所以 String 有常量池来保存很多常量对象。
常量池 每个class一份,存在于字节码文件中。常量池中有字面量(数量值、字符串值)和符号引用(类符号引用、字段符号引用、方法符号引用),虚拟机指令根据这张常量表找到要执行的类名、方法名、参数类型、字面量等类型
运行时常量池
运行时常量池每个class一份,存在于方法区中(元空间)。当类加载到内存中后,jvm就会将class常量池中的内容存放到运行时常量池中,经过解析(resolve)之后,也就是把符号引用替换为直接引用,解析的过程会去查询全局字符串池(StringTable),以保证运行时常量池所引用的字符串与全局字符串池中所引用的是一致的。 jdk1.7之前,运行时常量池(包含着字符串常量池)都在方法区,具体的hotspot虚拟机实现为永久代 jdk1.7阶段,字符串常量池从方法区移到堆中,运行池常量池剩下的部分依旧在方法区(剩下类信息、属性信息、方法信息等),同样是hotspot中的永久代 jdk8中方法区的实现是元空间(metaspace),专门用来存元数据。和永久代不同的是元空间并不在虚拟机中,而是使用本地内存
字符串常量池
每个JVM中只有一份,存在于方法区中(堆)。全局字符串池里的内容是在类加载完成,经过验证,准备阶段之后在堆中生成字符串对象实例,然后将该字符串对象实例的引用值存到string pool中(string pool中存的是引用值而不是具体的实例对象,具体的实例对象是在堆中开辟的一块空间存放的)。 在HotSpot VM里实现的string pool功能的是一个StringTable类,它是一个哈希表,里面存的是驻留字符串(用双引号括起来的引用而不是驻留字符串实例本身),也就是说在堆中的某些字符串实例被这个StringTable引用之后就等同被赋予了”驻留字符串”的身份。
2.3 String 对象的实例化
2.3.1 常见构造方法
方法名 | 说明 |
---|---|
public String() | 创建一个空白字符串对象,不含有任何内容 |
public String(char[] chs) | 根据字符数组的内容,来创建爱你字符串对象 |
public String(String original) | 根据传入的字符串内容,来创建爱你字符串对象 |
String s = “abc” | 直接赋值的方式创建字符串对象,内容就是abc |
示例代码
package com.lhl.string;
public class Demo2StringConstructor {
/*
String类常见构造方法:
public String() : 创建一个空白字符串对象,不含有任何内容
public String(char[] chs) : 根据字符数组的内容,来创建字符串对象
public String(String original) : 根据传入的字符串内容,来创建字符串对象
String s = “abc”; 直接赋值的方式创建字符串对象,内容就是abc
注意:
String这个类比较特殊, 打印其对象名的时候, 不会出现内存地址
而是该对象所记录的真实内容.
面向对象-继承, Object类
*/
public static void main(String[] args) {
// public String() : 创建一个空白字符串对象,不含有任何内容
String s1 = new String();
System.out.println(s1);
// public String(char[] chs) : 根据字符数组的内容,来创建字符串对象
char[] chs = {'a','b','c'};
String s2 = new String(chs);
System.out.println(s2);
// public String(String original) : 根据传入的字符串内容,来创建字符串对象
String s3 = new String("123");
System.out.println(s3);
}
}
2.3.2 静态方法
方法名 | 说明 |
---|---|
public static String valueOf(char data[]) {} | 返回指定数组的 String |
public static String valueOf(char data[], int offset, int count){} | 返回指定数组的 String(指定子数组的开始索引和子数组的长度) |
public static String valueOf(xx value) {} | public static String valueOf(xx value) {} |
package com.lhl.string;
/**
* @author lhl
* @ClassName DemoStaticConstructor
* @description TODO
* @data 2022/04/14 11:02
* @Version V1.0
**/
public class DemoStaticConstructor {
public static void main(String[] args) {
char[] chs = {'我', '爹', '是', '厂', '长'};
//public static String valueOf(char data[]) {}
String s = String.valueOf(chs);
System.out.println("s = " + s);
//public static String valueOf(char data[], int offset, int count){}
String s1 = String.valueOf(chs, 0, 2);
System.out.println("s1 = " + s1);
//public static String valueOf(xx value) {}
Object obj = "hello,靓仔";
String s2 = String.valueOf(obj);
System.out.println("s2 = " + s2);
}
}
2.3.3 使用 ""
+
任意数据类型和 "字符串"
进行拼接,结果都是字符串。
数组+”字符串”,结果是数组的地址值+”字符串”
package com.lhl.string;
/**
* @author lhl
* @ClassName AppendDemo
* @description TODO
* @data 2022/04/14 11:05
* @Version V1.0
**/
public class AppendDemo {
public static void main(String[] args) {
int num = 123456;
String s = num + "";
System.out.println("s = " + s);
}
}
2.3.4 创建字符串对象的区别对比
- 通过构造方法创建
通过 new 创建的字符串对象,每一次 new 都会申请一个内存空间,虽然内容相同,但是地址值不同 - 直接赋值方式创建
以""
方式给出的字符串,只要字符序列相同(顺序和大小写),无论在程序代码中出现几次,JVM 都只会建立一个 String 对象,并在字符串池中维护 - 字符串常量池
当使用双引号常见字符串常量的时候,系统会自动检查该字符串是否在字符串常量池中存在,不存在:创建;存在:不会重新创建,而是直接使用。
ps:字符串常量池从JDK7版本开始,从方法区中挪到了堆内存 - 通过拼接方式
原则:
- 常量+常量:结果是常量池。
- 常量和变量 或 变量和变量:结果是堆。
2.4 字符串创建面试踩坑
public class Test1{
public static void main(Stirng[] args){
//ture
String s1="abc";
String s2="abc";
System.out.println(s1==s2);
}
}
public class Test2{
public static void main(Stirng[] args){
//false
String s1="abc";
String s2=new String("abc");//这个代码实际上是创建了两个对象,双引号是第一个,new是第二个;此种方式费内存
System.out.println(s1==s2);
}
}
public class Test3{
public static void main(Stirng[] args){
//false
String s1="abc";
String s2="ab";
String s3=s1+"c";//注意,此地方是变量+字符串
System.out.println(s1==s2);
}
}
public class Test4{
public static void main(Stirng[] args){
//ture
String s1="abc";
String s2="a"+"b"+"c";//Java中存在常量优化机制,在编译的时候,就会将"a"+"b"+"c"拼接为"abc";
System.out.println(s1==s2);
}
}
2.5 字符串对象的比较
== 比较基本数据类型:比较的是具体的值
== 比较引用数据类型:比较的是对象地址值
2.5.1 equals() 方法
字符串是对象,它比较内容是否相同,通过一个方法来实现的,这个方法叫:equals();
String 类重写了Object类的 equals() 方法
public boolean equals(String s) //比较两个字符串内容是否相同、区分大小写
public boolean equalsIgnoreCase(String anotherString) //比较字符串内容, 忽略大小写
public class Demo1Equals {
public static void main(String[] args) {
String s1 = "abc";
String s2 = "ABC";
String s3 = "abc";
// equals : 比较字符串内容, 区分大小写
System.out.println(s1.equals(s2));
System.out.println(s1.equals(s3));
// equalsIgnoreCase : 比较字符串内容, 忽略大小写
System.out.println(s1.equalsIgnoreCase(s2));
}
}
2.5.2 空字符串的比较
什么是空字符串: 空字符串的长度是 0 。
示例代码:
public class Test { public static void main(String[] args) { String s1 = ""; String s2 = new String(); String s3 = new String(""); System.out.println(s1); System.out.println(s2); System.out.println(s3); } }
如何判断某个字符串是否为空字符串
示例代码:
public class Test { public static void main(String[] args) { String str = ""; if ("".equals(str)) { System.out.println("是空字符串"); } } }
public class Test { public static void main(String[] args) { String str = ""; if (null != str && str.isEmpty()) { System.out.println("是空字符串"); } } }
public class Test { public static void main(String[] args) { String str = ""; if(null != str && str.equals("")){ System.out.println("是空字符串"); } } }
public class Test { public static void main(String[] args) { String str = ""; if(null != str && str.length() ==0){ System.out.println("是空字符串"); } } }
2.6 字符串常用方法&应用案例
2.6.1 常用系列
public boolean isEmpty() {} | 字符串是否为空: |
---|---|
public int length() {} | 返回字符串的长度 |
public String concat(String str) {} | 拼接,等价于 + |
public boolean equals(Object anObject){} | 比较字符串是否相等,区分大小写 |
public int compareTo(String anotherString){} | 比较字符串大小,区分大小写,按照 Unicode 编码值比较大小 |
public String toLowerCase(){} | 将字符串中大写字母转为小写 |
public String toUpperCase(){} | 将字符串中小写字母转为大写 |
public String trim(){} | 去掉字符串前后空白符 |
示例代码:
public class Test {
public static void main(String[] args) {
String str = "hello world";
String s = str.toUpperCase();
System.out.println("将字符串中的小写字母转换为大写字母 = " + s);
String str2 = "Hello WorLD";
String s1 = str2.toLowerCase();
System.out.println("将字符串中的大写字母转换为小写字母 = " + s1);
String str3 = " hello world ";
String s3 = str3.trim();
System.out.println("去掉字符串前后空白符 = " + s3);
}
}
应用案例:
键盘录入一个字符串,使用程序实现在控制台遍历该字符串
实现步骤 :
- 键盘录入一个字符串,用 Scanner 实现
- 遍历字符串,首先要能够获取到字符串中的每一个字符,
public char charAt(int index)
:返回指定索引处的char值,字符串的索引也是从0开始的 - 遍历字符串,其次要能够获取到字符串的长度,
public int length():
返回此字符串的长度 - 遍历打印
代码实现 :
package com.lhl.test;
import java.util.Scanner;
public class Test2 {
/*
需求:键盘录入一个字符串,使用程序实现在控制台遍历该字符串
思路:
1. 键盘录入一个字符串,用 Scanner 实现
2. 遍历字符串,首先要能够获取到字符串中的每一个字符
public char charAt(int index):返回指定索引处的char值,字符串的索引也是从0开始的
3. 遍历字符串,其次要能够获取到字符串的长度
public int length():返回此字符串的长度
4. 遍历打印
9
*/
public static void main(String[] args) {
// 1. 键盘录入一个字符串,用 Scanner 实现
Scanner sc = new Scanner(System.in);
System.out.println("请输入:");
String s = sc.nextLine();
// 2. 遍历字符串,首先要能够获取到字符串中的每一个字符
for(int i = 0; i < s.length(); i++){
// i : 字符串的每一个索引
char c = s.charAt(i);
System.out.println(c);
}
}
}
2.6.2 查找和获取字符系列
public boolean contains(CharSequence s){} | 字符串中是否包含子串 |
---|---|
public int indexOf(String str){} | 从前往后查找字符串中的子串,如果有,有返回第一次出现的下标;否则,返回 -1 |
public int lastIndexOf(String str){} | 从后往前查找字符串中的子串,如果有,有返回第一次出现的下标;否则,返回 -1 |
public char charAt(int index){} | 返回 index 位置的字符: |
public char[] toCharArray(){} | 将此字符串转换为一个新的字符数组返回 |
public class Test {
public static void main(String[] args) {
String str = "hello world";
String str2 = "or";
boolean contains = str.contains(str2);
if (contains) {
System.out.println(str + "中是否包含" + str2);
}
int index = str.indexOf(str2);
System.out.println(str2 + "在" + str + "中从前往后查找的索引是:" + index);
index = str.lastIndexOf(str2);
System.out.println(str2 + "在" + str + "中从后往前的索引是:" + index);
}
}
应用案例:
键盘录入一个字符串,使用程序实现在控制台遍历该字符串
实现步骤 :
- 键盘录入一个字符串,用 Scanner 实现
- 将字符串拆分为字符数组 ,
public char[] toCharArray( ):
将当前字符串拆分为字符数组并返回 - 遍历字符数
代码实现 :
package com.lhl.test;
import java.util.Scanner;
public class Test3 {
/*
需求:键盘录入一个字符串,使用程序实现在控制台遍历该字符串
思路:
1. 键盘录入一个字符串,用 Scanner 实现
2. 将字符串拆分为字符数组
public char[] toCharArray( ):将当前字符串拆分为字符数组并返回
3. 遍历字符数组
*/
public static void main(String[] args) {
// 1. 键盘录入一个字符串,用 Scanner 实现
Scanner sc = new Scanner(System.in);
System.out.println("请输入:");
String s = sc.nextLine();
// 2. 将字符串拆分为字符数组
char[] chars = s.toCharArray();
// 3. 遍历字符数组
for (int i = 0; i < chars.length; i++) {
System.out.println(chars[i]);
}
}
}
2.6.3 截取、替换、切割
截取:
//从传入的索引位置处,向后截取,一直截取到末尾,得到新的字符串并返回
String substring(int beginIndex) :
// 从beginIndex索引位置开始截取,截取到endIndex索引位置,得到新字符串并返回(包含头,不包含尾)
String substring(int beginIndex, int endIndex) :
案例需求 :
以字符串的形式从键盘接受一个手机号,将中间四位号码屏蔽 最终效果为:156**1234
实现步骤 :**
- 键盘录入一个字符串,用 Scanner 实现
- 截取字符串前三位
- 截取字符串后四位
- 将截取后的两个字符串,中间加上进行拼接,输出结果 ```java package com.lhl.test;
import java.util.Scanner;
public class Test5 { / 需求:以字符串的形式从键盘接受一个手机号,将中间四位号码屏蔽 最终效果为:156*1234
思路:
1. 键盘录入一个字符串,用 Scanner 实现
2. 截取字符串前三位
3. 截取字符串后四位
4. 将截取后的两个字符串,中间加上****进行拼接,输出结果
*/
public static void main(String[] args) {
// 1. 键盘录入一个字符串,用 Scanner 实现
Scanner sc = new Scanner(System.in);
System.out.println("请输入手机号:");
String telString = sc.nextLine();
// 2. 截取字符串前三位
String start = telString.substring(0,3);
// 3. 截取字符串后四位
String end = telString.substring(7);
// 4. 将截取后的两个字符串,中间加上****进行拼接,输出结果
System.out.println(start + "****" + end);
}
}
**替换:**
```java
//1. 将当前字符串中的target内容,使用replacement进行替换,返回新的字符串
String replace(CharSequence target, CharSequence replacement)
应用案例:
键盘录入一个 字符串,如果字符串中包含(TMD),则使用*替换
实现步骤 :**
- 键盘录入一个字符串,用 Scanner 实现
- 替换敏感词
String replace(CharSequence target, CharSequence replacement)
将当前字符串中的target内容,使用replacement进行替换,返回新的字符串 - 输出结果
代码实现 :
package com.lhl.test;
import java.util.Scanner;
public class Test6 {
/*
需求:键盘录入一个 字符串,如果字符串中包含(TMD),则使用***替换
思路:
1. 键盘录入一个字符串,用 Scanner 实现
2. 替换敏感词
String replace(CharSequence target, CharSequence replacement)
将当前字符串中的target内容,使用replacement进行替换,返回新的字符串
3. 输出结果
*/
public static void main(String[] args) {
// 1. 键盘录入一个字符串,用 Scanner 实现
Scanner sc = new Scanner(System.in);
System.out.println("请输入:");
String s = sc.nextLine();
// 2. 替换敏感词
String result = s.replace("TMD","***");
// 3. 输出结果
System.out.println(result);
}
}
切割:
//根据传入的字符串作为规则进行切割,将切割后的内容存入字符串数组中,并将字符串数组返回
String[] split(String regex)
案例需求 :
以字符串的形式从键盘录入学生信息,例如:“张三 , 23”
从该字符串中切割出有效数据,封装为Student学生对象
实现步骤 :
- 编写Student类,用于封装数据
- 键盘录入一个字符串,用 Scanner 实现
- 根据逗号切割字符串,得到(张三)(23)
String[] split(String regex) :根据传入的字符串作为规则进行切割
将切割后的内容存入字符串数组中,并将字符串数组返回 - 从得到的字符串数组中取出元素内容,通过Student类的有参构造方法封装为对象
- 调用对象getXxx方法,取出数据并打印。
代码实现 :
package com.lhl.test;
import com.lhl.domain.Student;
import java.util.Scanner;
public class Test7 {
/*
需求:以字符串的形式从键盘录入学生信息,例如:“张三 , 23”
从该字符串中切割出有效数据,封装为Student学生对象
思路:
1. 编写Student类,用于封装数据
2. 键盘录入一个字符串,用 Scanner 实现
3. 根据逗号切割字符串,得到(张三)(23)
String[] split(String regex) :根据传入的字符串作为规则进行切割
将切割后的内容存入字符串数组中,并将字符串数组返回
4. 从得到的字符串数组中取出元素内容,通过Student类的有参构造方法封装为对象
5. 调用对象getXxx方法,取出数据并打印。
*/
public static void main(String[] args) {
// 2. 键盘录入一个字符串,用 Scanner 实现
Scanner sc = new Scanner(System.in);
System.out.println("请输入学生信息:");
String stuInfo = sc.nextLine();
// stuInfo = "张三,23";
// 3. 根据逗号切割字符串,得到(张三)(23)
String[] sArr = stuInfo.split(",");
// System.out.println(sArr[0]);
// System.out.println(sArr[1]);
// 4. 从得到的字符串数组中取出元素内容,通过Student类的有参构造方法封装为对象
Student stu = new Student(sArr[0],sArr[1]);
// 5. 调用对象getXxx方法,取出数据并打印。
System.out.println(stu.getName() + "..." + stu.getAge());
}
}
2.6.4 编码和解码
编码:
//编码,将字符串转换为字节数组,按照平台默认的字符编码进行编码:
public byte[] getBytes(){}
//编码,按照指定的编码方式进行编码:
public byte[] getBytes(Charset charset){}
解码:
//解码,将字节数组转换为字符串,按照平台默认的字符编码进行解码:
public String(byte bytes[]) {}
public String(byte bytes[], int offset, int length){}
//解码,按照指定的编码方式进行解码:
public String(byte bytes[], Charset charset){}
public String(byte bytes[], String charsetName) throws UnsupportedEncodingException{}
示例代码:
2.6.5 正则表达式
- 正则表达式:用来专门处理字符串的技术。
- 字符类:
[abc]
:只能是 a 或 b 或 c 。[^abc]
:除了 a 、b 、c 以外的任意一个字符。[a-zA-Z]
:必须是 a - z ,A - Z 中的任意一个字符。[^a-zA-Z]
:除了 a - z ,A - Z 中的任意任意一个字符。
- 数字类:
[0-9]
:只能是 0 和 9 之间的任意一个数字。\d
:等同于[0-9]
。[^0-9]
:除了 0 和 9 之间的任意一个数字。\D
:等同于[^0-9]
。
- 预定于字符类:
.
:匹配所有字符。\d
:等同于[0-9]
。\D
:等同于[^0-9]
。\w
:等同于[a-zA-Z_0-9]
。\W
:等同于[^a-zA-Z_0-9]
。
- 边界匹配器:
^
:行的开头。$
:行的结尾。
数量类:
X?
:X 字符最多只能出现一次( 0 次或 1 次)。X*
:X 字符可以出现 0 次、1 次或 多次。X+
:X 字符可以出现 1 次或多次。X{n}
:X 字符只能出现 n 次。X{n*,}
:X 字符至少出现 n 次(在数学中表示 [n,+∞) )。X{n,m}
:X 字符只能出现 n 到 m 次(在数学中表示 [n,m] )。
字符串是否匹配指定的正则表达式:
public boolean matches(String regex){}
示例代码: ```java package com.github.string2.demo8;
/**
- 手机号码的规则:
- 开头必须是1,长度规定11。
- 第二位 3 - 9
- 第三位到最后一位 0 - 9
*/
public class Test {
public static void main(String[] args) {
} } ```String iphone = "15367492341"; boolean matches = iphone.matches("^1[3-9]\\d{9}$"); System.out.println("matches = " + matches);
2.6.6 拓展练习
练习1
- 在字符串中找出连续最长数字串,返回这个串的长度,并打印这个最长数字串。
- 例如:abcd12345cd125se123456789,返回 9 ,打印出123456789。
public class Test { public static void main(String[] args) { String str = "abcd12345cd125se123456789"; String[] split = str.split("[a-zA-Z]+"); String max = ""; for (String s : split) { if (s.length() > max.length()) { max = s; } } System.out.println("最长的字符串是:" + max + ",它的长度是:" + max.length()); } }
练习2
需求:
将字符串中指定部分进行反转。比如将 “abcdefgho” 反转为 “abfedcgho” 。
示例代码:
public class Test {
public static void main(String[] args) {
String str = "abcdefgho";
String reverse = reverse(str, 2, 5);
System.out.println("reverse = " + reverse); // abfedcgho
}
public static String reverse(String str, int start, int end) {
char[] chars = str.toCharArray();
for (int i = start, j = end; i < j; i++, j--) {
char temp = chars[i];
chars[i] = chars[j];
chars[j] = temp;
}
return new String(chars);
}
}
练习3
- 计算字符串 B(例如:ab )在字符串 A(例如: dsabdnabdsnabeabiwpabekabd)中出现的次数。
实现思路:
- ① 对字符串进行索引查找 indexOf。
- ② 找到字符串的索引记录,进行字符串截取。
- ③ 直到找到位置,indexOf 的方法是 -1 。
④ 一旦找到,计数器 +1 。
public class Test { public static void main(String[] args) { String a = "dsabdnabdsnabeabiwpabekabd"; String b = "ab"; int times = times(a, b); System.out.println("times = " + times); } /** * 字符串出现的次数 * * @param str 字符串A * @param sub 字符串B * @return 返回字符串B在字符串A中出现的次数 */ public static int times(String str, String sub) { int count = 0; // 计数器 int index; // 定义变量,记录字符串查找后的索引 while ((index = str.indexOf(sub)) != -1) { // 计数器+1 count++; // 截取字符串 str = str.substring(index + sub.length()); } return count; } }
练习4
计算一个字符串中每个字符出现的次数
实现步骤:1.使用Scanner获取用户输入的字符串 2.创建Map集合,key是字符串中的字符,value是字符的个数 3.遍历字符串,获取每一个字符串 3.1 String类的方法toCharArray,把字符串转换为一个字符数组,遍历数组 3.2 String类的方法length()+charAt(索引) 4.使用获取到的字符,去Map集合中判断key是否存在 4.1使用Map集合中的方法containsKey(获取到的字符),返回的是boolean值: true:字符存在,通过字符(key)获取value(字符个数) value++ put(key,value)把新的value存储到Map集合中 false:字符不存在,把字符作为 key,1作为value存储到map集合中。 put(key,1) 4.2使用Map集合中的get(key) 返回null,key不存在 不是null,可以存在
```java import java.util.HashMap; import java.util.Scanner;
public class MapTest {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println(“请输入一个字符串:”);
String str = sc.next();
HashMap
```