相关链接
目录
All From 传智培训课程 + 后期自己整理补充内容
P9 【常用API】Scanner,Object,String,StringBuilder,递归
1 API概述
1.1 API概念
- API(Application Programming Interface) 应用程序编程接口 / 帮助文档
- 编写一个机器人程序去控制机器人踢足球,程序就需要向机器人发出向前跑、向后跑、射门、抢球等各种命令,没有编过程序的人很难想象这样的程序如何编写。
- 但是对于有经验的开发人员来说,知道机器人厂商一定会提供一些用于控制机器人的Java类,这些类中定义好了操作机器人各种动作的方法。
- 其实,这些Java类就是机器人厂商提供给应用程序编程的接口,大家把这些类称为API。
- 本章涉及的Java API指的就是JDK中提供的各种功能的Java类
1.2 快速使用API步骤
-
A:打开帮助文档
-
B:点击显示,找到索引,看到输入框
-
C:你要学习什么内容,你就在框框里面输入什么内容
-
举例:Random
-
-
D:看包
-
java.lang
包下的类在使用的时候是不需要导包的
-
-
E:看类的描述
-
Random类是用于生成随机数的类
-
-
F:看构造方法
- Random():无参构造方法
- Random r = new Random();
-
G:看成员方法
-
public int nextInt(int n) //产生的是一个[0,n)范围内的随机数
-
调用方法:
-
a.看返回值类型:人家返回什么类型,你就用什么类型接收
-
b.看方法名:名字不要写错了
-
c.看形式参数:人家要几个参数,你就给几个,人家要什么数据类型的,你就给什么数据类型的
-
图例
-
应用实例:
int number = r.nextInt(100);
-
-
2 Scanner类
-
API文档
-
Scanner类作用
- 用Scanner类的方法可以完成接收键盘录入的数据,接收的数据类型为基本数据类型和字符串类型。
2.1 Scanner类使用案例
案例代码一 Scanner类接受键盘录入的字符串
package com.groupies.base.day09;
import java.util.Scanner;
/**
* @author GroupiesM
* @date 2021/3/29
* @introduction Scanner类接收键盘录入的字符串
*
* Scanner:用于获取键盘录入数据。(基本数据类型,字符串数据)
* public String nextLine():获取键盘录入字符串数据
*/
public class Demo1Scanner {
public static void main(String[] args) {
//创建键盘录入对象
Scanner sc = new Scanner(System.in);
//接收数据
System.out.println("请输入一个字符串");
String line = sc.nextLine();
//输出结果
System.out.println("line:" + line);
}
}
3 Object类
- API文档
-
Object类作用
- Object是类层次结构的根类,所有的类都直接的或者间接的继承自该类。
3.1 Object类的toString()方法
案例代码二 Object类的toString()方法 【2.a 学生类重写tostring()】
package com.groupies.base.day09;
/**
* @author GroupiesM
* @date 2021/3/29
* @introduction 学生类 Object类的toString()方法
*
* Object:是类层次结构的根类,所有的类都直接的或者间接的继承自该类。
* 构造方法:Object()
*
* 直接输出对象名,输出底层调用的是该对象的toString()
*
* 查看API,我们发现建议所有子类都重写toString()。
* 到底该如何重写该方法呢?自动生成的就可以。
*/
public class Demo2POJOStudent {
private String name;
private int age;
public Demo2POJOStudent() {
};
public Demo2POJOStudent(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
//第一次打印student对象时还没有重写toString方法,打印出来的是一串地址值
//由于所有类的都默认继承Object类,所以也可以使用父类的toString(),默认打印了包名+类名+@+内存地址
//重写tostring()可以自定义实现打印输出的结果
public String toString() {
return "Demo2POJOStudent[" +
"name='" + name + '\'' +
", age=" + age +
']';
}
}
案例代码二 Object类的toString()方法 【2.b 测试类】
package com.groupies.base.day09;
/**
* @author GroupiesM
* @date 2021/3/29
* @introduction 学生类的测试类 Object类的toString()方法
*
* Object:是类层次结构的根类,所有的类都直接的或者间接的继承自该类。
* 构造方法:Object()
*
* 直接输出对象名,输出底层调用的是该对象的toString()
*
* 查看API,我们发现建议所有子类都重写toString()。
* 到底该如何重写该方法呢?自动生成的就可以。
*/
public class Demo2ObjectMethodToString {
public static void main(String[] args) {
Demo2POJOStudent studnet = new Demo2POJOStudent();
studnet.setName("林青霞");
studnet.setAge(30);
//1。重写toString方法前: com.groupies.base.day09.Demo2POJOStudent@23fc625e
//2. 重写toString方法后:Demo2POJOStudent[name='林青霞', age=30]
System.out.println(studnet);
/* //按住ctrl点击println查看打印方法的源码
public void println(Object x) {//相当于子类对象赋值给父类的引用--多态的方式向上转型,即=> Object x = student;
String s = String.valueOf(x);
synchronized (this) {
println(s);
}
}
*/
/* //再次按住ctrl点击valueOf方法查看源码,因为student对象不为null,所以实际上又调用了toString方法
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
*/
///输出结果与直接打印对象名一致
//直接输出对象名,输出底层调用的是该对象的tostring()
System.out.println(studnet.toString());
/* //再次按住ctrl点击toString方法查看源码 返回的是类名+包名+@+内存的哈希地址
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
*/
}
}
3.2 Object类的equals()方法
案例代码三 Object类的equals()方法 【3.a 学生类重写equals()】
package com.groupies.base.day09;
/**
* @author GroupiesM
* @date 2021/3/30
* @introduction 学生类 Object类的equals()方法
* ==:
* 可以比较基本数据类型,比较基本数据类型的时候比较的是基本数据类型的值是否相同
* 也可以比较引用数据类型,比较引用数据类型的时候比较的是引用数据类型的地址值是否相同
*
* 而我们现在想比较的是对象的内容是否相同?该怎么办呢?
* 通过查看API,我们找到了比较对象是否相等的方法:
* public boolean equals(Object obj)
* Object类中的equals()方法默认比较的是对象的地址是否相同。
* 如果我们想比较对象的内容是否相同,就必须自己重写该方法。
*
* 如何重写该方法呢?
* 自动生成即可。IDEA中快捷键 alt + insert
*/
public class Demo3POJOStudent {
private String name;
private int age;
public Demo3POJOStudent() {
}
public Demo3POJOStudent(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public boolean equals(Object obj) {
//执行语句:s1.equals(s2)
//this:表示 s1
//obj: 表示 s2
//没有加括号的if语句只能控制一个分号内的方法体,s1==s2不成立,所以此条return true不执行
if (this == obj) return true;
// obj == null -- 比较的对象是否为空(不成立)
// getClass() != obj.getClass() -- 比较的对象是否不是同一个类的对象,如果不是同一个类的则没有比较的意义(不成立)
// a||b表示:当a、b有一个为真时,结果为真。a、b都为假时结果为假。
// false || false => false 所以此条return false不执行
if (obj == null || getClass() != obj.getClass()) return false;
//obj向下转型(强转)
Demo3POJOStudent that = (Demo3POJOStudent) obj;
// a&&b表示:当a、b都为真时,结果为真。有一个为假或者都为假时结果为假。
// age == that.age 表示 s1.age == s2.age 判断结果为true
// name.equals(that.name) 表示 s1.name == equals(s2.name) 比较字符内容是否相同,判断结果为true
// true && true => true ;所以此条 return true 给测试类Demo3ObjectMethodEquals
return age == that.age && name.equals(that.name);
}
}
案例代码三 Object类的equals()方法 【3.b 测试类】
package com.groupies.base.day09;
/**
* @author GroupiesM
* @date 2021/3/29
* @introduction 学生类的测试类 Object类的equals()方法
*
* ==:
* 可以比较基本数据类型,比较基本数据类型的时候比较的是基本数据类型的值是否相同
* 也可以比较引用数据类型,比较引用数据类型的时候比较的是引用数据类型的地址值是否相同
*
* 而我们现在想比较的是对象的内容是否相同?该怎么办呢?
* 通过查看API,我们找到了比较对象是否相等的方法:
* public boolean equals(Object obj)
* Object类中的equals()方法默认比较的是对象的地址是否相同。
* 如果我们想比较对象的内容是否相同,就必须自己重写该方法。
*
* 如何重写该方法呢?
* 自动生成即可。IDEA中快捷键 alt + insert
*/
public class Demo3ObjectMethodEquals {
public static void main(String[] args) {
Demo3POJOStudent s1 = new Demo3POJOStudent("林青霞", 30);
Demo3POJOStudent s2 = new Demo3POJOStudent("林青霞", 30);
//Demo3POJOStudent对象 重写equals方法前:【false】
//Demo3POJOStudent对象 重写equals方法前:【true】
System.out.println(s1.equals(s2));//true
/* //按住ctrl查看equals()源码 底层判断的是 s1==s2,引用数据类型用==比较的是地址值
public boolean equals(Object obj) {
return (this == obj);
}
*/
//s1,s2代表实例的引用 位于栈中,真正的对象实例存储在堆中,s1,s2存储了其实例在堆中的内存地址
//重写equals方法前,比较的是s1,s2的地址值,因为是两个不同对象,所以地址值不同,结果为【false】
//重写equals方法后,我们指定比较两者的属性值,结果为【true】
Integer a = 123;
Integer b = 123;
System.out.println(a == b);//true
}
}
4 String类
-
API文档
-
String类概述
- 通过JDK提供的API,查看String类的说明
- A:"abc"是String类的一个实例,或者成为String类的一个对象
- B:字符串字面值"abc"也可以看成是一个字符串对象
- C:字符串是常量,一旦被赋值,就不能被改变
- D:字符串本质是一个字符数组
-
String类的构造方法
- String(String original):把字符串数据封装成字符串对象
- String(char[] value):把字符数组的数据封装成字符串对象
- String(char[] value, int index, int count):把字符数组的一部分数据封装成字符串对象
4.1 String类4种常用构造方法
案例代码四 String类4种常用构造方法
package com.groupies.base.day09;
/**
* @author GroupiesM
* @date 2021/3/30
* @introduciton String类4种常用构造方法
*
* String:代表字符串类。
* 由多个字符组成的一串数据。
* 字符串的本质就是一个字符数组。
*
* String的构造方法:
* 方式1. String(String original):把字符串数据封装成字符串对象
* 方式2. String(char[] value):把字符数组的数据封装成字符串对象
* 方式3. String(char[] value, int index, int count):把字符数组的一部分数据封装成字符串对象
* 方式4. String():最常用的 API中表示(Java程序中所有字符串字面值 如“abc”都作为此类的实例实现)
* public String toString():返回此对象本身(它已经是一个字符串!)。
*/
public class Demo4StringConstructor {
public static void main(String[] args) {
//方式1. String(String original):把字符串数据封装成字符串对象
String s1 = new String("hello1");
/*如果打印的不是 包名+类名+@+地址 则表示String类重写了toString方法*/
System.out.println(s1);//hello1
System.out.println("--------");
//方式2. String(char[] value):把字符数组的数据封装成字符串对象
char[] value2 = {'h', 'e', 'l', 'l', 'o', '2'};
String s2 = new String(value2);
System.out.println(s2);//hello2
System.out.println("--------");
//方式3. String(char[] value, int index, int count):把字符数组的一部分数据封装成字符串对象
char[] value3 = {'h', 'e', 'l', 'l', 'o', '3', '3', '3'};
String s3 = new String(value3, 0, value3.length - 2);
System.out.println(s3);//hello3
//方式4. String():最常用的
String s4 = "hello4";
System.out.println(s4);
}
}
4.2 String类创建对象两种方式
- 内存图
案例代码五 String创建对象两种方式
package com.groupies.base.day09;
/**
* @author GroupiesM
* @date 2021/3/30
* @introduction String创建对象两种方式
*
* String类创建对象的特点:
* A:通过构造方法创建对象
* B:通过直接赋值的方式创建对象
*
* 这两种方式的创建是有区别的:
* 1.通过构造方法创建的字符串对象是在堆内存。
* 2.通过直接赋值的方式创建的字符串对象是在方法区的常量池。
*
*/
public class Demo5StringNew {
public static void main(String[] args) {
String s1 = new String("hello");
String s2 = new String("hello");
String s3 = "hello";
String s4 = "hello";
System.out.println(s1 == s2);//false
System.out.println(s1 == s3);//false
System.out.println(s3 == s4);//true
}
}
4.3 String类练习之模拟用户登录
- boolean equals(Object obj)
- 比较字符串的内容是否相同
- boolean equalsIgnoreCase(String str)
- 比较字符串的内容是否相同,忽略大小写
- 需求
- 模拟登录,给三次机会,并提示还有几次
案例代码六 **String类练习之模拟用户登录 **
package com.groupies.base.day09;
import java.util.Scanner;
/**
* @author GroupiesM
* @date 2021/3/30
* @introduction String类练习之模拟用户登录
*
* 需求:模拟登录,给三次机会,并提示还有几次
* 分析:
* A:定义两个字符串对象,用于存储已经存在的用户名和密码
* B:键盘录入用户名和密码
* C:拿键盘录入的用户名和密码去跟已经存在的用户名和密码进行比较
* 如果内容相同,就提示登录成功
* 如果内容不同,就提示登录失败,并提示还有几次机会
* public boolean equals(Object anObject):比较字符串的内容,严格区分大小写(用户名和密码)
* public boolean equalsIgnoreCase(String anotherString):比较字符串的内容,不考虑大小写(验证码)
*/
public class Demo6StringLogIn {
public static void main(String[] args) {
//定义两个字符串对象,用于存储已经存在的用户名和密码
String username = "admin";
String password = "admin";
//循环次数
int count = 0;
//键盘录入的用户名
String scName;
//键盘录入的密码
String scPassword;
//创建键盘录入对象
Scanner sc = new Scanner(System.in);
//模拟登陆,给三次机会
while (count < 3) {
System.out.println("请输入用户名:");
scName = sc.nextLine();
System.out.println("请输入密码");
scPassword = sc.nextLine();
//事件A: 用户名相等
boolean a = scName.equals(username);
//事件B: 密码相等
boolean b = scPassword.equals(password);
//事件C: 错误次数小于3
boolean c = count < 2;
if (a && b) {
System.out.println("登录成功");
break;
//用户名或密码任意一个不低,且登录次数小于3,提示次数,并重新输入
} else if (c) {
System.out.println("登陆失败,你还有" + (2 - count) + "次机会");
//用户名或密码任意一个不对,且登录次数大于3,锁定账号,并跳出循环
} else {
System.out.println("你的账号被锁定,请与管理员联系");
break;
}
//每次循环次数加1
count++;
}
}
}
4.4 String类的获取功能
-
public char charAt(int index)
- 返回指定索引处的值
-
public int length()
- 返回字符串中的字符个数,字符串的长度
- 需求
- 遍历字符串(获取字符串中的每一个字符)
案例代码七 **String类遍历字符串 **
package com.groupies.base.day09;
/**
* @author GroupiesM
* @date 2021/3/30
* @introduction String类遍历字符串
*
* 需求:遍历字符串(获取字符串中的每一个字符)
*/
public class Demo7StringFor {
public static void main(String[] args) {
//要遍历字符串,你首先得有一个字符串
String s = "abcde";
//思考:如何获取字符串中的每一个字符
//假如让我们来提供方法,我们应该提供一个根据索引返回指定位置的字符的方法
//返回值:char
//形式参数:int index
//public char charAt(int index):返回指定索引处的值
//原始做法
System.out.println(s.charAt(0));
System.out.println(s.charAt(1));
System.out.println(s.charAt(2));
System.out.println(s.charAt(3));
System.out.println(s.charAt(4));
System.out.println("-------------------");
for (int i = 0; i < s.length(); i++) {
System.out.println(s.charAt(i));
}
System.out.println("-----");
//用for循环改进
//public int length():返回字符串中的字符个数,字符串的长度
for (int x = 0; x < s.length(); x++) {
System.out.println(s.charAt(x));
}
}
}
4.5 String类字符串拼接
- 需求
- 把数组中的数据按照指定个格式拼接成一个字符串
案例代码八 **String类字符串拼接 **
package com.groupies.base.day09;
/**
* @author GroupiesM
* @date 2021/3/30
* @introduction String类字符串拼接
*
* 需求:把数组中的数据按照指定个格式拼接成一个字符串
* 举例:int[] arr = {1,2,3};
* 输出结果:[1, 2, 3]
*
* 分析:
* A:定义一个int类型的数组
* B:写方法实现把数组中的元素按照指定的格式拼接成一个字符串
* C:调用方法
* D:输出结果
*/
public class Demo8IntArrayToString {
public static void main(String[] args) {
//定义一个int类型的数组
int[] arr = {1, 2, 3};
String result = arrayToString(arr);
System.out.println(result);
}
/**
* @introduction 将int类型数组中的元素按照指定的格式拼接成一个字符串的方法
* @param arr int类型数组
* @return 特定格式字符串
*/
public static String arrayToString(int[] arr) {
String s = "[";
for (int i = 0; i < arr.length; i++) {
s += arr[i];
//如果不是最后一个元素,则再拼个逗号 ,
if (i != arr.length - 1) {
s += ",";
//如果是最后一个元素,则再拼个右括号 ]
} else {
s += "]";
}
}
return s;
}
}
4.6 String类字符串反转
- 需求
- 字符串反转
案例代码九 String类字符串反转
package com.groupies.base.day09;
import java.util.Scanner;
/**
* @author GroupiesM
* @date 2021/3/30
* @introduction String类字符串反转
*
* 需求:字符串反转
* 举例:键盘录入”abc”
* 输出结果:”cba”
*
* 分析:
* A:键盘录入字符串数据
* B:写方法实现字符串数据的反转
* 把字符串倒着遍历,在把每一个得到的字符拼接成一个字符串
* C:调用方法
* D:输出结果
*/
public class Demo9StringReverse {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个字符串");
String s = sc.nextLine();
//写方法实现字符串数据的翻转
//调用方法
String result = reverse(s);
//输出结果
System.out.println(result);
}
/**
* @introduction 反转字符串的方法
* @param source 源字符串
* @return 反转后的字符串
*/
public static String reverse(String source) {
String result = "";
//反向for循环
for (int i = source.length() - 1; i >= 0; i--) {
result += source.charAt(i);
}
return result;
}
}
5 StringBuilder类
-
API文档
-
StringBuilder类概述
- StringBuilder:是一个可变的字符串。字符串缓冲区类。
-
String和StringBuilder的区别
- String的内容是固定的
- StringBuilder的内容是可变的
-
String类+=拼接字符串耗费内存原因
- String类的+=每次拼接都会产生新的字符串对象
- 而利用StringBuilder来拼接字符串自始至终用的都是同一个StringBuilder容器
注:这里的JVM图例是JDK7及以前版本,从JDK8起,元空间取代永久代,常量池已移至堆中
5.1 SB类的构造方法
案例代码十 StringBuilder类的构造方法
package com.groupies.base.day09;
import com.sun.org.apache.xpath.internal.operations.String;
/**
* @author GroupiesM
* @date 2021/3/30
* @introduciton StringBuilder类的构造方法
*
* StringBuilder:是一个可变的字符串类。
*
* String和StringBuilder的区别:
* String的内容是固定的。
* StringBuilder的内容是可变的。
*
* 构造方法
* public StringBuilder()
* public StringBuilder(String str)
*
* public String toString():返回此序列中数据的字符串表示形式。
*/
public class Demo10StringBuilder {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
System.out.println("sb:" + sb);//sb:
System.out.println(sb.length());//0
//public StringBuilder(String str)
StringBuilder sb2 = new StringBuilder("helloWorld");
System.out.println("sb2" + sb2);
System.out.println(sb2.length());
}
}
5.2 SB类三个常用API、链式编程
- public String toString()
- 返回此序列中数据的字符串表示形式。
- public StringBuilder append(任意类型)
- 添加数据,并返回对象本身。
- public StringBuilder reverse()
- 反转字符串,并返回对象本身。
案例代码十一 StringBuilder类的3个常用API
package com.groupies.base.day09;
/**
* @author GroupiesM
* @date 2021/3/30
* @introduciton StringBuilder类的3个常用API、链式编程
*
* A.转字符串功能
* public String toString():返回此序列中数据的字符串表示形式。
* B.添加功能
* public StringBuilder append(任意类型):添加数据,并返回对象本身。
* C.反转功能
* public StringBuilder reverse():反转字符串,并返回对象本身。
*/
public class Demo11StringBuilderAPI {
public static void main(String[] args) {
/*A.转字符串功能
public String toString():返回此序列中数据的字符串表示形式。*/
StringBuilder sb1 = new StringBuilder("abc");
String s1 = sb1.toString();
/*B.添加功能
public StringBuilder append(任意类型):添加数据,并返回对象本身。*/
//将sb地址赋值给sb3
StringBuilder sb2 = new StringBuilder();
StringBuilder sb3 = sb2.append("hello");
System.out.println("sb:" + sb2);//sb2:hello
System.out.println("sb3:" + sb3);//sb3:hello
System.out.println(sb2 == sb3);//比较地址值:相等 true
StringBuilder sb4 = new StringBuilder();
sb4.append("hello");
//append(任意类型)
sb4.append(true);
sb4.append(100);
System.out.println("sb4:" + sb4);//sb4:hellotrue100
//链式编程(每个.append前面所有内容都是一个对象整体)
StringBuilder sb5 = new StringBuilder();
sb5.append("hello").append("world").append(true).append(100);
System.out.println("sb5:" + sb5);//sb5:helloworldtrue100
/*C.反转功能
public StringBuilder reverse()*/
sb5.reverse();
System.out.println("sb5.reverse():" + sb5);//sb5.reverse():001eurtdlrowolleh
}
}
5.3 SB类与String类转换
案例代码十二 StringBuilder和String通过方法完成相互转换
package com.groupies.base.day09;
/**
* @author GroupiesM
* @date 2021/3/30
* @introduction StringBuilder和String通过方法完成相互转换
*
* StringBuilder和String的相互转换
*
* A.StringBuilder --> String
* public String toString():通过toString()就可以实现把StringBuilder转换为String
*
* B.String -- StringBuilder
* public StringBuilder(String s):通过构造方法就可以实现把String转换为StringBuilder
*/
public class Demo12StrinbBuilderAndString {
public static void main(String[] args) {
//StringBuilder --> String
StringBuilder sb1 = new StringBuilder();
sb1.append("hello");
//错误做法 直接将对象赋值给字符串基本类型 String s1 = sb1;
//正确做法 使用StringBuilder的toString()返回字符串 String s1 = sb1.toString();
String s1 = sb1.toString();
System.out.println(s1);
//String --> StringBuilder
String s2 = "hello";
StringBuilder sb2 = new StringBuilder(s2);
System.out.println(sb2);
}
}
5.4 SB类从数组拼接字符串
案例代码十三 StringBuilder和String通过方法完成相互转换
package com.groupies.base.day09;
/**
* @author GroupiesM
* @date 2021/3/30
* @introduction 利用StringBuilder把数组拼接成一个字符串
*
* 把数组拼接成一个字符串
* 举例:int[] arr = {1,2,3};
* 输出结果:[1, 2, 3]
*
* 分析:
* A:定义一个int类型的数组
* B:写方法实现把数组中的元素按照指定的格式拼接成一个字符串
* C:调用方法
* D:输出结果
*/
public class Demo13IntArrayToStringBuilder {
public static void main(String[] args) {
//定义一个int类型的数组
int[] arr = {1, 2, 3};
//写方法实现把数组中的元素按照指定的格式拼接成一个字符串
//调用方法
String result = arrayToString(arr);
//输出结果
System.out.println("result:" + result);//result:[1,2,3]
}
/**
* @introduction 将int类型数组中的元素按照指定的格式拼接成一个字符串的方法
* @param arr int类型数组
* @return 特定格式字符串
*/
public static String arrayToString(int[] arr) {
StringBuilder sb = new StringBuilder("[");
for (int i = 0; i < arr.length; i++) {
sb.append(arr[i]);
//如果不是最后一个元素,则再拼个逗号 ,
if (i != arr.length - 1) {
sb.append(",");
//如果是最后一个元素,则再拼个右括号 ]
} else {
sb.append("]");
}
}
//通过StringBuilder的toString返回字符串类型
return sb.toString();
}
}
5.5 SB类的字符串反转
案例代码十四 利用StringBuilder完成字符串反转
package com.groupies.base.day09;
import java.util.Scanner;
/**
* @author GroupiesM
* @date 2021/3/30
* @introduciton 利用StringBuilder完成字符串反转
*
* 把字符串反转
* 举例:键盘录入”abc”
* 输出结果:”cba”
*
* 分析:
* A:键盘录入一个字符串数据
* B:写方法实现字符串数据的反转
* String -- StringBuilder -- reverse() -- String
* C:调用方法
* D:输出结果
*/
public class Demo14StringBuilderReverse {
public static void main(String[] args) {
//键盘录入一个字符串数据
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个字符串:");
String s = sc.nextLine();
//写方法实现字符串数据的反转
//调用方法
String result = myReverse(s);
//输出结果
System.out.println("result:" + result);
}
/**
* @introduction 利用StringBuilder完成字符串反转
* @param s 原字符串
* @return 反转后的字符串
*/
public static String myReverse(String s) {
return new StringBuilder(s).reverse().toString();
}
}
6 递归
-
递归:把大问题拆成很多小问题,然后再把小问题拆成更多的小问题,
- 当我们把更多小问题解决了,小问题也解决了
- 随着小问题的解决,大问题也随之解决了
- 在方法本身不断的调用方法自己
-
递归注意事项:
- 递归一定要有出口,否则会内存溢出
- 递归次数不宜过多,否则会内存溢出
6.1 递归方法求阶乘
案例代码十五 使用递归方法求阶乘
package com.groupies.base.day09;
/**
* @author GroupiesM
* @date 2021/3/30
* @introduction 使用递归方法求阶乘
*
* 需求:求5的阶乘
* 5! = 5 * 4 * 3 * 2 * 1; //120
* 5! = 5 * 4!; //120
* 4! = 4 * 3!; //24
* 3! = 3 * 2!; //6
* 2! = 2 * 1!; //2
* 1! = 1; //1
* n! = n * (n - 1)!
*
* 递归:把大问题拆成很多小问题,然后再把小问题拆成更多的小问题,
* 当我们把更多小问题解决了,小问题也解决了
* 随着小问题的解决,大问题也随之解决了
* 在方法本身不断的调用方法自己
*
* 递归注意事项:
* 递归一定要有出口,否则会内存溢出
* 递归次数不宜过多,否则会内存溢出
*
* public void show(int n) {//5
* //出口
* if(n == 0) {
* return;
* }
*
* show(n - 1);
* }
*
* 从前有座山,山里有个庙,庙里有个老和尚,老和尚在给小和尚讲故事
* 从前有座山,山里有个庙,庙里有个老和尚,老和尚在给小和尚讲故事
* 从前有座山,山里有个庙,庙里有个老和尚,老和尚在给小和尚讲故事
* 从前有座山,山里有个庙,庙里有个老和尚,老和尚在给小和尚讲故事
* 从前有座山,山里有个庙,庙里有个老和尚,老和尚在给小和尚讲故事
* ...
*
* 学习编程...找工作...赚钱...娶媳妇...生娃娃
* 学习编程...找工作...赚钱...娶媳妇...生娃娃
* 学习编程...找工作...赚钱...娶媳妇...生娃娃
* 学习编程...找工作...赚钱...娶媳妇...生娃娃
* 学习编程...找工作...赚钱...娶媳妇...生娃娃
* ...
*/
public class Demo15Recursion {
public static void main(String[] args) {
System.out.println(recursion(5));
}
/**
* @introduction 求一个数的阶乘
* @param n
* @return n的阶乘结果 n!
*/
public static int recursion(int n) {
//必须要有出口
if (n == 1) {
return 1;
} else {
return n * recursion(n - 1);
}
}
}
6.2 递归方法求斐波那契列数
JavaSE入门 P4 【Java基础】数组 的 3.3 数组操作之不死神兔 中,使用数组的方式解决过这个问题
这次则采用递归的方式求解
案例代码十六 使用递归方法求斐波那契列数
package com.groupies.base.day09;
/**
* @author GroupiesM
* @date 2021/3/30
* @introduction 递归求斐波那契列数
*
* 古典问题:有一对兔子,从出生后第2个月起每个月都生一对兔子,
* 小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,
* 问第二十个月的兔子对数为多少?
*
*
* 1个月:1
* 2个月:2
* 3个月:3
* 4个月:5
* 5个月:8
* 6个月:13
* 7个月:21
*
* 规律:除了第一个月和第二月以外,其余每个月都是前两个月之和
* 斐波那契列数
*/
public class Demo16Recursion {
public static void main(String[] args) {
System.out.println(method(1, 19));//开始1对兔子,19个月后共有6765对兔子
}
/**
* @introduction month个月后 init个数量对兔子会发展成为多少对兔子数
* @param init 初始兔子数量
* @param month 月份
* @return 结果兔子数量
*/
public static int method(int init, int month) {
//必须要有出口
//如果是第一个月,只有一对兔子
if (month == 1) {
return init;
} else if (month == 2) {
return init * 2;
} else {
return method(init, month - 2) + method(init, month - 1);
}
}
}
7 课后练习
7.1 练习1 String校验QQ号
练习1 String校验QQ号
package com.groupies.base.day09;
import java.util.Scanner;
/**
* @author GroupiesM
* @date 2021/3/31
* @introduction 课后基础练习1 String校验QQ号
*
* 需求说明:请用户输入一个“QQ号码”,我们来判断这个QQ号码是否正确。
* 要求:
* 1、这个QQ号长度在5到12之间
* 2、这个QQ号必须是全部数字
* 3、不能以0开头 (这里可以用到String类的startsWith方法)
*
*/
public class HomeWork1 {
public static void main(String[] args) {
//键盘录入一个QQ号码字符串
System.out.println("请输入一个QQ号码");
Scanner sc = new Scanner(System.in);
String qq = sc.next();
//调用checkQQ(String qq)方法验证QQ号
boolean checkResult = checkQQ(qq);
//打印验证结果
System.out.println("这个QQ号码是否正确:" + checkResult);
}
/**
* @introduction 验证QQ号码是否符合规则的方法
* @param qq 待验证的QQ号码
* @return 是否符合QQ号验证规则
*/
public static boolean checkQQ(String qq) {
//2、这个QQ号必须是全部数字
for (int i = 0; i < qq.length(); i++) {
if (qq.charAt(i) < '0' || qq.charAt(i) > '9') {
return false;
}
}
//1、这个QQ号长度在5到12之间
if (qq.length() < 5 || qq.length() > 12) {
return false;
}
//3、不能以0开头 (这里可以用到String类的startsWith方法)
else if (qq.startsWith("0")) {
return false;
//如果都不满足条件,则返回true:符合验证规则
} else {
return true;
}
}
}
7.2 练习2 char与int转换和计算
练习2 char与int转换和计算
package com.groupies.base.day09;
import java.util.Scanner;
/**
* @author GroupiesM
* @date 2021/4/1
* @introduction 课后基础练习2 char与int转换和计算
*
* 分析以下需求,并用代码实现
* 1.键盘录入一个字符串
* 2.将该字符串变成字符数组(不能使用toCharArray()方法)
* 3.将字符数组中的所有大写字母变成小写字母(不能使用toLowerCase()方法)
* 4.如果第一位和最后一位的内容不相同,则交换
* 5.将字符数组中索引为偶数的元素变成’~’(波浪号)
* 6.打印数组元素的内容
*/
public class HomeWork2 {
public static void main(String[] args) {
//1.键盘录入一个字符串
System.out.println("请输入任意字符串");
Scanner sc = new Scanner(System.in);
//调用method方法处理字符串
char[] charArr = method(sc.next());
System.out.print("修改后的字符串为:");
//6.打印数组元素的内容
for (char c : charArr) {
System.out.print(c);
}
}
/**
* @introduction
* 1.键盘录入一个字符串
* 2.将该字符串变成字符数组(不能使用toCharArray()方法)
* 3.将字符数组中的所有大写字母变成小写字母(不能使用toLowerCase()方法)
* 4.如果第一位和最后一位的内容不相同,则交换
* 5.将字符数组中索引为偶数的元素变成’~’(波浪号)
* 6.打印数组元素的内容
* @param str 键盘录入的字符串
* @return 按规则修改后的字符串
*/
public static char[] method(String str) {
/*
System.out.println(Integer.valueOf('a'));//97
System.out.println(Integer.valueOf('z'));//122
System.out.println(Integer.valueOf('A'));//65
System.out.println(Integer.valueOf('Z'));//90
System.out.println((char) (Integer.valueOf('A') + 32));//a
*/
//动态初始化char类型数组,数组长度=字符串长度
char[] arr = new char[str.length()];
int strToInt;
char start = str.charAt(0);
char end = str.charAt(str.length() - 1);
//2.将该字符串变成字符数组(不能使用toCharArray()方法)
for (int i = 0; i < str.length(); i++) {
strToInt = Integer.valueOf(str.charAt(i));
if (i % 2 == 0) {
arr[i] = '~';
}
//3.将字符数组中的所有大写字母变成小写字母(不能使用toLowerCase()方法)
else if (strToInt >= 65 && strToInt <= 90) {
arr[i] = (char) (strToInt + 32);
} else {
arr[i] = str.charAt(i);
}
}
//4.如果第一位和最后一位的内容不相同,则交换
if (start == end) {
arr[0] = end;
arr[str.length()] = start;
}
return arr;
}
}
7.3 练习3 3种方式反转字符串
练习3 3种方式反转字符串
package com.groupies.base.day09;
import java.util.Scanner;
/**
* @author GroupiesM
* @date 2021/4/1
* @introduction 课后基础练习3 3种方式反转字符串
*
* 键盘录入一个字符串,然后对他进行反转,用3种方法实现
*/
public class HomeWork3 {
public static void main(String[] args) {
System.out.println("请输入任意字符串");
Scanner sc = new Scanner(System.in);
String next = sc.next();
//第一种方法 StringBuilder.reverse()
StringBuilder method1 = new StringBuilder(next);
System.out.println("第一种方法(StringBuilder.reverse()):\r\n " + method1.reverse());
System.out.println("=====================");
//第二种方法 反向遍历字符串
String method2 = "";
for (int i = next.length() - 1; i >= 0; i--) {
method2 += next.charAt(i);
}
System.out.println("第二种方法(反向遍历字符串):\r\n " + method2);
System.out.println("=====================");
//第三种方法 toCharArray后遍历交换
char[] method3Arr = next.toCharArray();
for (int i = 0; i < method3Arr.length / 2; i++) {
char temp = method3Arr[i];
method3Arr[i] = method3Arr[method3Arr.length - 1 - i];
method3Arr[method3Arr.length - 1 - i] = temp;
}
String method3 = new String(method3Arr);
System.out.println("第二种方法(toCharArray后遍历交换):\r\n " + method3);
}
}
7.4 练习4 首字母转大写 其余小写
练习4 首字母转大写 其余小写
package com.groupies.base.day09;
import java.util.Scanner;
/**
* @author GroupiesM
* @date 2021/4/1
* @introduciton 课后基础练习4 首字母转大写 其余小写
*
* 键盘录入一个字符串,把该字符串的首字母转成大写,其余为小写。(只考虑英文大小写字母字符)
*/
public class HomeWork4 {
public static void main(String[] args) {
System.out.println("请输入任意字符串");
//录入一个字符串
Scanner sc = new Scanner(System.in);
System.out.println("转换后的字符串为:" + method(sc.next()));
}
/**
* @introduction 把该字符串的首字母转成大写,其余为小写。(只考虑英文大小写字母字符)
* @param str 键盘录入的字符串
* @return 转换后的字符串
*
* System.out.println(Integer.valueOf('a'));//97
* System.out.println(Integer.valueOf('z'));//122
* System.out.println(Integer.valueOf('A'));//65
* System.out.println(Integer.valueOf('Z'));//90
* System.out.println((char) (Integer.valueOf('A') + 32));//a
*
*/
public static String method(String str) {
int strToInt;
//动态初始化char类型数组,数组长度=字符串长度
char[] arr = new char[str.length()];
//将该字符串变成字符数组(不能使用toCharArray()方法)
for (int i = 0; i < str.length(); i++) {
strToInt = Integer.valueOf(str.charAt(i));
//把该字符串的首字母转成大写
if (strToInt >= 97 && strToInt <= 122 && i == 0) {
arr[i] = (char) (strToInt - 32);
}
//其余为小写(只考虑英文大小写字母字符)
else if (strToInt >= 65 && strToInt <= 90 && i > 0) {
arr[i] = (char) (strToInt + 32);
} else {
arr[i] = str.charAt(i);
}
}
//返回字符类型转换结果
return new String(arr);
}
}
7.5 练习5 比较字符串出现次数
练习5 比较字符串出现次数
package com.groupies.base.day09;
import java.util.Scanner;
/**
* @author GroupiesM
* @date 2021/4/1
* @introduction 课后基础练习5 比较字符串出现次数
*
* 分析以下需求,并用代码实现
* 1.键盘录入一个大字符串,再录入一个小字符串
* 2.统计小字符串在大字符串中出现的次数
* 3.代码运行打印格式:
* 请输入大字符串:郑庄公齐桓公鲁庄公晋文公楚庄王秦穆公
* 请输入小字符串:公
* 控制台输出:5
*
* 思路:循环使用int indexOf(String str) 方法 若返回值不为-1,就进行累加,最终输出计数器的值
* (注意:还需要用到字符串的截取方法subString)
*/
public class HomeWork5 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入第一个大字符串");
String first = sc.next();
System.out.println("请输入第二个小字符串");
String second = sc.next();
System.out.println("小字符串在大字符串中出现的次数为:" + method(first, second));
}
public static int method(String first, String second) {
//小字符串长度,也是每次截取大字符串的长度
int subLength = second.length();
//循环长度
int forLength = first.length() - second.length();
//截取大字符串
String firstSubStr;
//记录小字符串在大字符串中出现的次数
int count = 0;
//循环判断每次截取的字符串是否和小字符串相等
for (int i = 0; i <= forLength; i++) {
firstSubStr = first.substring(i, i + subLength);
count = firstSubStr.equals(second) ? count + 1 : count;
}
//返回计数结果
return count;
}
}
7.6 练习6 String.indexOf()
练习6 String.indexOf()
package com.groupies.base.day09;
/**
* @author GroupiesM
* @date 2021/4/1
* @introduction 课后基础练习6 String.indexOf()
*
* 需求说明:
* 定义如下字符串:
* String str = "abcrwabcgreabcrqrgqoabcrw";
* 统计”abc”在str中出现的次数
*
* 思路:循环使用int indexOf(String str) 方法 若返回值不为-1,就进行累加,最终输出计数器的值
* (注意:还需要用到字符串的截取方法subString)
*/
public class HomeWork6 {
public static void main(String[] args) {
//定义大串
String max = "abcrwabcgreabcrqrgqoabc";
//定义小串
String min = "abc";
//int count = 0;
String subStr;
//定义计数器变量
int count = 0;
//定义索引
int index = 0;
//循环判断小串是否在大串中出现
//1,int i = max.indexOf(min) //2
//2,int index = i;
//3,index != -1
while((index = max.indexOf(min)) != -1) { //说明查找到了字符ch出现的位置
count++; //出现的次数累加1
max = max.substring(index + min.length());//更新max字符串中的内容
}
System.out.println(count);
}
}
7.6 练习7 StringBuilder.insert()
练习7 StringBuilder.insert()
package com.groupies.base.day09;
import java.util.Random;
/**
* @author GroupiesM
* @date 2021/4/1
* @introduction 课后基础练习7 StringBuilder.insert()
*
* insert(offset,i)
* offset:插入位置索引
* i:插入值,可以是数字 字符等,原理是方法的重载
*
* 分析以下需求,并用代码实现
* 1.定义String getStr()方法
* 功能描述:这个方法会返回长度为5的随机字符串,要求这个字符串,包含4个大写字母和1个数字。
*
* 例如:ABCD9、9ABCD、AB9CD。。。都是符合要求的随机字符串
* 提示:自学StringBuilder的insert方法,这个方法可以做
*
* 2.定义好getStr方法后,就在主方法中,测试一下这个方法好不好用
*/
public class HomeWork7 {
public static void main(String[] args) {
System.out.println(getStr());
}
/**
* @introduction 返回长度为5的随机字符串,这个字符串,包含4个大写字母和1个数字
* @Step 首先将A-Z的字符放入char[]数组,随机从数组中取出4个字符后,在随机插入一个数字到随机位置
* @return 返回字符串
*/
public static String getStr() {
//获取26个大写的英文字母存到一个数组里面
char[] arr = new char[26];
int index = 0;
for (int i = 'A'; i <= 'Z'; i++) {
arr[index] = (char) i;
index++;
}
//创建随机对象
Random r = new Random();
//获取4个大写字母
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 4; i++) {
int num = r.nextInt(26);
sb.append(arr[num]);
}
//随机插入位置的索引0-4
int offset = r.nextInt(5);
//随机插入的数值0-9
int i = r.nextInt(10);
//随机插入数字到字符串中
sb.insert(offset, i);
//返回生成好的随机
return sb.toString();
}
}
8 附件 【常用API】
=======================String=====================
String构造方法://构造方法,创建对象
String(String original):把字符串数据封装成字符串对象//String s = new String("abc")
String(char[] value):把字符数组的数据封装成字符串对象//char[] value = {'h','e','l','l','o'};
//String ch = new String(value);
String(char[] value, int index, int count):把字符数组中的一部分数据封装成字符串对象//String s3 = new String(value,0,3);
判断功能
boolean equals(Object obj):比较字符串的内容是否相同
boolean equalsIgnoreCase(String str):比较字符串的内容是否相同,忽略大小写
boolean startsWith(String str):判断字符串对象是否以指定的str开头
boolean endsWith(String str):判断字符串对象是否以指定的str结尾
获取功能
int length():获取字符串的长度,其实也就是字符个数
char charAt(int index):获取指定索引处的字符
int indexOf(String str):获取str在字符串对象中第一次出现的索引//如果没有出现索引,则index值为-1
String substring(int start):从指定的下标开始一直截取到最后(包含这个下标对应的文字)
String substring(int start,int end):截取指定的范围的字符串(包含头,不包含尾)
字符串的遍历.
for(int x=0; x<s.length(); x++) {
System.out.println(s.charAt(x));}
字符数组的遍历
for (int i = 0; i < ch.length; i++) {
System.out.println(ch[i]);}
转换方法
char[] toCharArray():把字符串转换为字符数组
String toLowerCase():把字符串转换为小写字符串
String toUpperCase():把字符串转换为大写字符串
去空格和分割功能
String trim():去除字符串两端空格
String[] split(String str):按照指定符号分割字符串
=======================StringBuilder=====================
public StringBuilder append(任意类型):添加数据,并返回自身对象
public StringBuilder reverse(): 反转
public String toString()//StringBuilder -- String
StringBuilder(String str)//String -- StringBuilder
=======================Arrays类===========================
public static String toString(int[] a):把数组转成字符串
public static void sort(int[] a):对数组进行升序排序
=======================Integer类===========================
Integer构造方法
Integer(int value) int类型转换成Integer
Integer(String s) String类型转换成Integer
int类型和String类型互转
String s1 = 100 + ""; //int -- String
int x = Integer.parseInt("100");//String -- int
String和char相互转换
String s2 = 'a' + ""; //char -- String
char ch = s2.charAt(0);//String -- char
=======================Date类===========================
Date类构造方法
Date():根据当前时间创建的日期对象
Date(long date):根据给定的毫秒值创建对象,从1970 年 1 月 1 日 00:00:00
Date类的成员方法
public long getTime():获取的是毫秒值。从1970年1月1日 00:00:00开始的。
public void setTime(long time):设置时间,给的是毫秒值。
=======================SimpleDateFormat类===========================
格式化(日期 -> 文本): Date -- String //对象转化为字符串
Date d = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String s = sdf.format(d);
解析(文本 -> 日期): String -- Date
String str = "2080-08-08 12:23:45";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d = sdf.parse(str);
21/04/01
M