Day08
API
概述:
全称Application Programming Interface,应用程序编程接口。
Java API:指的就是JDK中提供的各种功能的Java类,这些类将底层的实现封装了起来,我们不需要关心这些类是如何实现的,只需要学习这些类是如何实现的即可,我们可以通过帮助文档来学习这些API如何使用
案例:键盘录入字符串并打印
import java.util.Scanner;
/*
通过查阅API文档知:实现键盘录入字符串的方法
是Scanner类下的nextLine()方法
*/
public class ScannerTest {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个字符串:");
//调用nextLine方法接收字符串
//ctrl+alt+v:快速生成方法的返回值
String s = sc.nextLine();
System.out.println(s);
}
}
运行结果:
- next():遇到了空格,就不再录入数据了
- 结束标记:空格,tab键
- nextLine():可以将数据完整的接收过来
- 结束标记:回车换行符
- 当nextInt和nextLine方法配合使用时,nextLine方法就没有键盘录入的机会了
- 建议:今后键盘录入数据的时候,如果是字符串和整数一起接收,建议使用next方法接收字符串
String
- String类在java.lang包下,所以使用的时候不需要导包
- java程序中,所拥有的双引号字符串,都是String这个类的对象
- 字符串是常量,他们的值在创建之后不能更改
String常见构造方法
- public String() 创建一个空白字符串对象,不含有任何内容
- public String(char[] chs) 根据字符数组的内容,来创建字符串对象
- public String(String original) 根据传入的字符串内容,来创建字符处对象
- String s = “abc”; 直接赋值的方式创建字符串对象,内容就是abc
/*
String这个类比较特殊,打印其对象名的时候不会出现内存地址,而
是该对象所记录的真实内容
*/
public class StringTest {
public static void main(String[] args) {
//public String()创建一个空白字符串对象,不含有任何内容
String s1 = new String();
System.out.println(s1);
//public String(char[] chs)根据字符数组的内容,来创建字符串对象
char[] ch = {'a','b','c'};
String s2 = new String(ch);
System.out.println(s2);
//public String(String original)根据传入的字符串内容,来创建字符处对象
String s3 = new String("123");
System.out.println(s3);
}
}
运行结果:
创建字符串对象的区别对比
==号做比较
基本数据类型:比较的是具体值
引用数据类型:比较地址值
以“”方式给出的字符串,只要字符序列相同(顺序和大小写),无论在程序代码中出现几次,JVM都只会建立一个String对象,并在字符串常量池中维护
字符串常量池:当使用双引号创建字符串对象的时候,系统会检查该字符串是否在字符串常量池中存在,若不存在则创建,存在则不会重新创建,而是直接复用
通过new创建的字符串对象,每一次new都会申请一个内存空间,虽然内容相同,但是地址值不同
结论:双引号创建的字符串对象,在字符串常量池中;通过构造方法创建的字符串对象,在堆内存中存储
String常见面试题
String s1 = "abc";
String s2 = "ab";
String s3 = s2+"c";
System.out.println(s1==s3);//此处结果为false
当字符串之间使用+号串联(拼接)的时候,系统会自动创建一个StringBuilder对象,然后再调用其append方法完成拼接,拼接后,再调用其toString方法转换为String类型。
String s1 = "abc";
String s2 = "a"+"b"+"c";
System.out.println(s1==s2);//此处结果为true
Java存在常量优化机制,在编译的时候,就会将"a"+“b”+“c"拼接为"abc”
字符串的比较
字符串是对象,它比较内容是否相同,是通过一个方法来实现的,这个方法叫:equals()
public boolean equals(Object anObject):将此字符串与指定对象进行比较。由于我们比较的是字符串对象,所以参数直接传递一个字符串
String s1 = "abc"; String s2 = "ABC"; String s3 = "abc"; System.out.println(s1.equals(s2)); //结果为false System.out.println(s1.equals(s3)); //结果为true //忽略大小写的比较 System.out.println(s1.equalsIgnoreCase(s2)); //结果为true
案例:用户登录
import java.util.Scanner;
public class LoginTest {
public static void main(String[] args) {
//定义两个字符串表示用户名和密码
String userName = "ahua";
String password = "123456";
Scanner sc = new Scanner(System.in);
for (int i = 1; i <= 3; i++) {
System.out.println("请输入用户名:");
//接收键盘录入的用户名
String name = sc.nextLine();
System.out.println("请输入密码:");
//接收间键盘录入的密码
String mima = sc.nextLine();
//判断输入的字符串和密码是否正确
if(name.equals(userName)&&mima.equals(password)){
System.out.println("登录成功!");
break;
}else{
if(i==3){
System.out.println("登录失败,您的次数已用完,账号已锁死。");
}else{
System.out.println("登录失败!您还剩"+(3-i)+"次机会。");
}
}
}
}
}
运行结果:
案例:遍历字符串
需求:键盘录入一个字符串,使用程序实现控制台遍历该字符串
思路1:
- 键盘录入一个字符串,用Scanner实现
- 遍历字符串,首先要能够获取到字符串中的每一个字符
- public char charAt(int index):返回指定索引处的char值,字符串的索引也是从0开始的
- 遍历字符串,其次要能够获取到字符串的长度
- public int length():返回此字符串的长度
- 数组的长度:数组名.length
- 字符串的长度:字符串对象.length()
import java.util.Scanner;
public class Bianli {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入:");
String s = sc.nextLine();
for (int i=0;i<s.length();i++){
char c = s.charAt(i);
System.out.print(c+" ");
}
}
}
运行结果:![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G5kitTUi-1607490546483)(C:\Users\花花\AppData\Roaming\Typora\typora-user-images\image-20201206113750689.png)]](https://img-blog.csdnimg.cn/20201209131415164.png)
思路2:
- 键盘录入一个字符串,用Scanner实现
- 将字符串拆分为字符数组
- public char[] toCharArray():将当前字符串拆分为字符数组并返回
- 遍历字符数组
import java.util.Scanner;
public class Bianli {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入:");
String s = sc.nextLine();
//将字符串拆分为字符数组
char[] chars = s.toCharArray();
//遍历字符数组
for (int i = 0; i < chars.length; i++) {
System.out.print(chars[i]+" ");
}
}
}
运行结果:
案例:统计字符次数
需求:键盘录入一个字符串,统计该字符串中大写字母字符,小写字母字符,数字字符出现的次数(不考虑其他字符)
思想:
- 键盘录入一个字符串,用Scanner实现
- 要统计三种类型的字符个数,需定义三个统计变量,初始值都为0
- 遍历字符串,得到每一个字符
- 判断该字符属于哪种类型,然后对应类型的统计变量+1
- 大写字母:ch>=‘A’&&ch<=‘Z’
- 小写字母:ch>=‘a’&&ch<=‘z’
- 数字:ch>=‘0’&&ch<=‘9’
- 输出三种类型的字符个数
import java.util.Scanner;
public class Bianli {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入:");
String s = sc.nextLine();
int big = 0;
int small = 0;
int num = 0;
//将字符串拆分为字符数组
char[] chars = s.toCharArray();
//遍历字符数组
for (int i = 0; i < chars.length; i++) {
char c = chars[i];
if(c>='A'&&c<='Z'){
big++;
}else if(c>='a'&&c<='z'){
small++;
}else if(c>='0'&&c<='9'){
num++;
}
}
System.out.println("大写字母个数:"+big);
System.out.println("小写字母个数:"+small);
System.out.println("数字个数:"+num);
}
}
运行结果:
案例:手机号屏蔽
需求:以字符串的形式从键盘接收一个手机号,将中间四位号码屏蔽,最终效果为167****1234
思路:
- 键盘录入一个字符串,用Scanner实现
- 截取字符串前三位
- 截取字符串:
- String substring(int beginIndex):从传入的索引位置处,向后截取,一直截取到末尾,得到新的字符串并返回
- String substring(int beginIndex,int endIndex):从beginIndex索引位置开始截取,截取到endIndex索引位置,得到新字符串并返回(包含头,不包含尾)
- String s1 = telString.substring(0,3);
- 截取字符串:
- 截取字符串后四位
- String s2 = telString.substring(7);
- 将截取后的两个字符串,中间加上****进行拼接,输出结果
import java.util.Scanner;
public class Jiequ {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入手机号:");
//定义字符串接收键盘传来的数据
String phone = sc.nextLine();
//截取字符串的前三位
String qian = phone.substring(0,3);
//截取字符串的后四位
String hou = phone.substring(7);
//拼接字符串
System.out.println(qian+"****"+hou);
}
}
运行结果:
案例:敏感词替换
需求:键盘录入一个字符串,如果字符串包含(TMD),则使用***替换
思路:
- 键盘录入一个字符串,用Scanner实现
- 替换敏感词
- String replace(CharSequence target,CharSequence replacement),将当前字符串中的target(被替换的旧值)内容,使用replacement(替换的新值)进行替换,返回新的字符串。
import java.util.Scanner;
public class Tihuan {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("口吐芬芳吧:");
//接收键盘录入数据
String s = sc.nextLine();
//替换敏感词
String result = s.replace("原地爆炸","***");
System.out.println(result);
}
}
运行结果:
案例:切割字符串
需求:以字符串的形式从键盘录入学生信息,例如:“阿花,22”从该字符串中切割出有效数据,封装为Student学生对象
- 编写Student类,用于封装数据
- 键盘录入一个字符串,用Scanner实现
- 根据逗号切割字符串,得到(张三)(22)
- String[] split(String regex):根据传入的字符串作为规则进行切割,将切割后的内容存入字符串数组中,并将字符串数组返回
模型类:
/*
1.split方法,切分字符串的时候,如果首为和末尾满足切分的规则,则效果是不一样的;(含头不含尾)
2.字符串中所有的方法都不会改变原字符串的值,运行后会得到一个新的字符串结果
*/
public class Student {
private String name;
private String age;
public Student() {
}
public Student(String name, String age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
测试类
import java.util.Scanner;
public class Qiege {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入学生信息:");
String s = sc.nextLine();
//将字符串按逗号分隔
String[] sArr = s.split(",");
//从得到的字符串数组中取出元素内容,通过Student类中的有参构造方法封装为对象
Student st = new Student(sArr[0],sArr[1]);
System.out.println(st.getName()+"..."+st.getAge());
}
}
运行结果:
String方法小结

补充:
1.split方法,切分字符串的时候,如果首为和末尾满足切分的规则,则效果是不一样的;(含头不含尾)
2.字符串中所有的方法都不会改变原字符串的值,运行后会得到一个新的字符串结果
public class Buchong {
public static void main(String[] args) {
String s = "abcdghklabcoiujkabc";
String[] arr = s.split("abc");
System.out.print("[");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]);
if(i!=arr.length-1){
System.out.print(",");
}else{
System.out.print("]");
}
}
System.out.println();
System.out.println("------------------");
s.toUpperCase();
System.out.println(s);
String ss = s.toUpperCase();
System.out.println(ss);
}
}
运行结果:
StringBuilder
概述
StringBuilder是一个可变的字符串类,我们可以把它看成是一个容器
作用是提高字符串的操作效率
StringBuilder构造方法
- publicStringBuilder() 创建一个空白可变字符串对象,不含有任何内容
- publicStringBuilder(String str) 根据字符串的内容,来创建可变字符串对象
StringBuilder sb = new StringBuilder();
System.out.println(sb); //输出结果为空
StringBuilder sb1 = new StringBuilder("abc");
System.out.println(sb1); //输出结果为:abc
StringBuilder常用方法
- public StringBuilder append(任意类型) //添加数据,并返回对象本身
- public StringBuilder reverse() //返回相反的字符序列
- public int length() //返回长度(字符出现的个数)
- public String toString //通过toString()就可以实现把StringBuilder转换为String
StringBuilder sb = new StringBuilder();
sb.append(123);
sb.append("abc");
sb.append(true);
System.out.println(sb); //输出结果:123abctrue
StringBuilder sb1 = new StringBuilder();
sb1.append("红色");
System.out.println(sb1); //输出结果:红色
sb1.append("黄色");
System.out.println(sb1); //输出结果:红色黄色
sb1.append("蓝色");
System.out.println(sb1); //输出结果:红色黄色蓝色
StringBuilder和String的区别
- String:内容是 不可变的
- StringBuilder:内容是可变的
案例:对称字符串
需求:键盘接收一个字符串,程序判断该字符串是否是对称字符串,并在控制台打印是或不是
思路:
- 键盘录入一个字符串,用Scanner实现
- 将键盘录入的字符串反转
- 使用反转后的字符串,和原字符串进行比对
- 如果相同,则输出是对称字符串,反之输出不是对称字符串
import java.util.Scanner;
public class Duichen {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入对称字符串:");
String s = sc.nextLine();
//将字符串进行翻转
//将字符串封装为StringBuilder对象,目的是为了调用其反转的方法
StringBuilder sb = new StringBuilder(s);
sb.reverse();
//将设sb转换为String类
String st = sb.toString();
//使用原字符串和反转后的字符串进行比较
if(s.equals(st)){
System.out.println("是对称字符串");
}else{
System.out.println("不是对称字符串");
}
}
}
运行结果:
StringBuilder和String相互转化
- StringBuilder转换为String
- public String toString():通过toString()就可以实现把StringBuilder转换为String
- String转换为StringBuilder
- public StringBuilder(String s):通过构造方法就可以实现把String转换为StringBuilder
案例:拼接字符串
需求:定义一个方法,把int数组中的数据按照指定的格式拼接成一个字符串返回,调用该方法,并在控制台输出结果。例如,数组为int[] arr = {2,4,5,2};执行方法后的输出结果为:[2,4,5,2]
思路:
- 定义一个int类型的数组,用静态初始化完成数组元素的初始化
- 定义一个方法,用于把int数组中的数据按照指定格式拼接成一个字符串返回。返回值类型String,参数列表int[] arr
- 在方法中调用StringBuilder按照要求进行拼接,并把结果转成String返回
- 调用方法,用一个变量接收结果
- 输出结果
public class Pinjie {
public static void main(String[] args) {
int[] arr = {2,4,5,2};
//调用方法并定义一个字符串接收返回的数据
String s = arrToString(arr);
System.out.println(s);
}
public static String arrToString(int[] arr){
//创建StringBuilder对象并添加一个"["
StringBuilder sb = new StringBuilder("[");
//遍历数组
for (int i = 0; i < arr.length; i++) {
//判断是否是打印最后一个数
if(i==arr.length-1){
sb.append(arr[i]).append("]");
}else {
sb.append(arr[i]).append(",");
}
}
return sb.toString();
}
}
运行结果:
练习1
自定义一个方法,让用户输入一个“QQ号码”,在方法中判断这个QQ号码是否合法。验证规则:(1)号码长度必须是5-12位数字;(2)首位不能是0;
import java.util.Scanner;
public class Lian1 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个QQ号:");
String s = sc.next();
isQQ(s);
}
public static void isQQ(String s){
//将输入的号码转换为字符数组
char[] c = s.toCharArray();
//判断号码长度是否合法
if(c.length>=5&&c.length<=12){
//遍历字符数组
for (int i = 0; i < c.length; i++) {
//判断号码首位是否合法
if(i==0){
//字符间的比较
if(c[i]<='0'||c[i]>'9'){
System.out.println("输入的号码不合法,首位必须是1-9的数字!");
return;
}
}else{
//判断首位后的是否合法
if(c[i]<'0'||c[i]>'9'){
System.out.println("输入的号码不合法,从第二个数起,数字必须是0-9!");
return;
}
}
}
System.out.println("你输入的号码合法!");
}else{
System.out.println("输入的号码不合法,长度必须是5-12位!");
}
}
}
运行结果:
练习2
键盘输入两个字符串,一个长,一个短,求短字符串在长字符串中出现的次数;
import java.util.Scanner;
/*
思路:
利用字符串的replace方法将长字符串中所有的短字
符串都替换成长度为0的空字符串,这样一来长字符
串的长度必然会减少,那么减少的量除以短字符串
的长度,就是短字符串在长字符串中出现的次数;
*/
public class Lian2 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个短字符串:");
String s1 = sc.next();
System.out.println("请输入一个含有多个短字符串的长字符串:");
String s2 = sc.next();
//将长字符串中的短字符串替换为空字符
String s3 = s2.replace(s1,"");
int num = (s2.length()-s3.length())/s1.length();
System.out.println("短字符串在长字符串中出现的次数为:"+num+"次。");
}
}
运行结果:
练习3
假如某网站希望使用5个随机小写字母作为随机验证码,请自定义一个方法,生成这样的一个验证码并返回;
import java.util.Random;
/*
小写字母的ASCII码的取值范围是97~122,所以可以
先随机生成97~122间的整数,然后在转换为对应字
符,即小写字母
*/
public class Lian3 {
public static void main(String[] args) {
char[] arr = vercode();
System.out.println("随机生成的5位验证码为:");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]);
}
}
public static char[] vercode(){
Random r = new Random();
//定义字符数组存储5个字符
char[] arr = new char[5];
//循环生成5个随机数
for (int i = 0; i < 5; i++) {
int a = r.nextInt(26)+97;
//将随机数转换为字符并存入数组
arr[i] = (char)a;
}
return arr;
}
}
运行结果:
练习4
自定义一个方法,完成随机生成一个6位数的验证码,验证码中可以包含大写字母,小写字母和数字,但是必须保证至少有一个数字,且数字的位置是随机的;
思路提示:
本题可以分成2个步骤完成,第一个步骤先生成一个6位数字符串验证码,不考虑至少一个数字的问题,第二步再解决至少一个数字的问题;
其中第一个步骤实现思路比较多,其中一种思路是提前准备好所有的合法字符,保存到一个数组中,然后随机从数组中选择6个字符出来,组成一个长度为6的字符串验证码,这个方式准备数组比较麻烦,但是也能实现;还有一种思路是直接生成6个指定范围的随机数字,然后把这6个数字强转成对应的字符即可;例如,你随机生成的数字是97–122,那么强转之后一定是一个小写字母,同理,可以生成大写字母和数字字符;
当第一个步骤完成后,可以利用StringBuilder类中的setChar方法,将指定索引位置的字符修改成指定的字符;或再第一步的时候,生成5位数的验证码,然后这一步利用StringBuilder类中的insert方法将指定的字符插入到指定索引位置,虽然这两个方法都可以完成效果,但是需要大家自行查询API学习使用;
import java.util.Random;
public class Lian4 {
public static void main(String[] args) {
//调用vercode方法并将返回的StringBuilder类型的字符串转换为String类型并赋值给s
String s = vercode().toString();
System.out.println("随机验证码为:");
System.out.println(s);
}
public static StringBuilder vercode(){
//定义一个长度为62的字符数组用来存储所有数字、小写字母、大写字母
char[] arr = new char[62];
int a = 48;
int b = 65;
int c = 97;
for (int i = 0; i < arr.length; i++) {
//索引0-9存储数字0-9,10-35存储大写字母A-Z,36-61存储小写字母a-z
if(i>=0&&i<=9){
arr[i] = (char)a;
a++;
}else if(i>9&&i<36){
arr[i] = (char)b;
b++;
}else{
arr[i] = (char)c;
c++;
}
}
// for (int i = 0; i < arr.length; i++) {
// System.out.print(arr[i]+" ");
// }
Random r = new Random();
//定义长度为5的字符数组存储5个随机字符
//char[] arr1 = new char[5];
//定义StringBuilder类型的字符串存储产生的随机字符
StringBuilder sb = new StringBuilder();
StringBuilder s = new StringBuilder();
for (int i = 0; i < 5; i++) {
//产生0-61的随机数,即随机索引
int l = r.nextInt(62);
//arr1[i] = arr[l];
//根据随机索引存储随机字符,通过append方法拼接成字符串给s
s = sb.append(arr[l]);
}
//System.out.println(s);
//随机产生插入位置的索引0-5
int i = r.nextInt(6);
//随机产生0-9插入到字符串中的指定索引出
int j = r.nextInt(10);
//通过insert方法向字符串中索引处插入字符j并赋值给s1
StringBuilder s1 = s.insert(i,j);
//System.out.println(s1);
return s1;
}
}
运行结果: