Java中String的学习
目录
String类简单介绍
- String类定义的变量可以用于存储字符串,同时String类提供了很多操作字符串的功能,我们可以直接使用
String 概述
-
java.lang.String 类代表字符串,String类定义的变量可以用于指向字符串对象,然后操作该字符串
-
Java程序中的所有字符串文字(例如"abc")都为此类的对象
-
String name = "小白"; String schoolName = "程序员"
-
String 类特点
- String其实常被成为不可变字符串类型,它的对象在创建后不可更改
- 以" "方式给出的字符串对象,在字符串常量池中存储
小结
- String是什么,可以做什么?
- 字符串类型,可以定义字符串变量指向字符串对象
- String是不可变字符串的原因?
- String变量每次的修改其实都是产生并指向了新的字符串对象
- 原来的字符串对象是没有改变的,所以称不可变字符串
创建字符串对象的2种方式
- 方式一:直接用" "定义。(推荐使用)
String name = "陈太帅";
- 方式二:通过String类的构造器来创建对象
构造器 | 说明 |
---|---|
public String() | 创建一个空白的字符串对象,不含有任何内容 |
public String(String original) | 根据传入的字符串内容,来创建字符串对象 |
public String(char[] chs) | 根据字符数组的内容,来创建字符串对象 |
public String (byte[] chs) | 根据字节数组的内容,来创建字符串对象 |
package com.string;
public class StringDemo01 {
public static void main(String[] args) {
//方式一:直接使用双引号得到字符串对象
String s = "我爱中国";
System.out.println(s);
//方式二:
//1.public String():创建一个空白字符串对象,不含有任何内容(几乎不用)
String s1 = new String();
System.out.println(s1);
//2.public String(String):根据传入的字符串内容,来传递字符串对象(几乎不用)
String s2 = new String("我是中国人");
System.out.println(s2);
//3.public String(char[] c ):根据字符串的内容,来创建字符串对象
char[] chars = {'a','b','中','国'};
String s3 = new String(chars);
System.out.println(s3);
//4.public String(byte[] b):根据字节数组的内容,来创建字符串对象
byte[] bytes = {97,98,99,65,66,67};
String s4 = new String(bytes);
System.out.println(s4);
System.out.println("----------------");
}
}
output:
我爱中国
我是中国人
ab中国
abcABC
----------------
区别
-
以 " "方式给出的字符串对象,在字符串常量池中存储,而且相同的内容只会在其中存储一份
-
通过构造器new对象,没new一次都会产生一个新对象,放在堆内存中。
-
String s1 = "abc"; String s2 = "abc"; System.out.println(s1 == s2);//true char[] chs = {'a','b','c'}; String s3 = new String(chs); String s4 = new String(chs); System.out.println(s3 == s4);//false
-
总结
- 字符串对象的特点:
- 双引号创建的字符串对象,在字符串常量池中存储同一个
- 通过new构造器创建的对象,在堆内存中分开存储
String类常见面试题
- 问题:下面代码的运行结果是?
public class Test{
public static void main(String[] args){
String s1 = new String("abc");//这句话实际上是创建了两个对象,在字符串常量池中创建了一个"abc",在堆内存中创建了一个"abc",此时s1指向堆内存中的对象地址
String s2 = "abc";//这句在内存没有创建对象,因为在字符串常量池中已经存在"abc"对象,s2指向字符串常量池的地址
System.out.println(s1 == s2);//false
}
}
- 试题2:
public class Test2{
public static void main(String[] args){
String s1 = "abc";//字符串常量池中
String s2 = "ab";
String s3 = s2 + "c";//s2是个变量,只要不是""直接给出来的,运算结果都是放在堆内存中的,s3指向堆内存中的abc
System.out.println(s1 == s3);//false
}
}
- 试题3:
public class Test3{
public static void main(String[] args){
String s1 = "abc";
String s2 = "a" + "b" + "c";
System.out.println(s1 == s2);//true
}
}
//Java存在编译优化机制,程序在编译时:"a" + "b" + "c"会直接转成"abc"
String 类常用API-字符串内容比较
字符串内容比较:
- 推荐使用String类提供的"equals" 比较:只关心内容一样
方法名 | 说明 |
---|---|
public boolean equals (Object anObject) | 将此字符串与指定对象比较。只关心字符内容是否一致! |
public Boolean equalsIgnoreCase(String anotherString) | 将此字符串与指定字符串比较,忽略大小写比较字符串,只关心字符串内容是否一致! |
package com.string;
import java.util.Scanner;
public class StringDemo02 {
public static void main(String[] args) {
//正确的用户名和密码
String okName = "csl";
String okPassword = "123123";
//2.请输入用户名和密码
while (true) {
Scanner sc = new Scanner(System.in);
System.out.println("用户名:");
String name = sc.next();
System.out.println("密码:");
String password = sc.next();
//3.判断用户输入的用户名和登录密码与正确内容是否相等
if (okName.equals(name) && okPassword.equals(password)){
System.out.println("登陆成功!");
break;
}else {
System.out.println("用户名或密码错误!");
}
}
//4.忽略大小写比较内容的API:一般用于比较验证码这样的业务逻辑
String sysCode = "23aHfW";
String code = "23AhFW";
System.out.println(sysCode.equals(code));
System.out.println(sysCode.equalsIgnoreCase(code));
}
}
output:
用户名:
csl
密码:
123123
登陆成功!
false
true
小结
- 如果字符串比较应该使用什么方式进行比较,为什么:
- 使用String提供的equals方法
- 只关心内容一样就返回true
- 开发中什么时候使用==比较数据
- 基本数据类型比较时使用
String常用API
方法名 | 说明 |
---|---|
public int length() | 返回此字符串的长度 |
public char charAt (int index) | 获取某个索引处的字符 |
public char[] toCharArray ( ) | 将当前字符串转换成字符数组并返回 |
public String substring (int beginIndex, int endIndex) | 根据开始和结束索引进行截取,得到新的字符串 [包前不包后) |
public String substring (int beginIndex) | 从传入索引处截取,截取到末尾,得到新的字符串 |
public String replace(CharSequence target,CharSequence replacement) | 使用新值将字符串中旧值替换,得到新的字符串 |
public String[] split(String regex) | 根据传入的规则切割字符串,得到字符串数组返回 |
package com.string;
public class StringDemo03 {
public static void main(String[] args) {
//1.public int lenth():获取字符的长度
String name = "我爱你中国China";
int length = name.length();
System.out.println(length);
//2.public char charAt(int index):获取某个索引位置处的字符
char c = name.charAt(3);
System.out.println(c);
System.out.println("------遍历字符串中的每个字符------");
for (int i = 0; i < name.length(); i++) {
char ch = name.charAt(i);
System.out.println(ch);
}
//3.public char[] toCharArray():把字符串类型转换为字符数组
char[] chars = name.toCharArray();
for (int i = 0; i < chars.length; i++) {
char ch = chars[i];
System.out.println(ch);
}
//4.public String substring(int beginIndex,int endIndex):截取内容,[包前不包后)
String name2 = "厉害了我的国loveMyCountry";
String s = name2.substring(0, 6);
System.out.println(s);
//5.public String substring(int beginIndex):从当前索引一直截取到结尾
String s1 = name2.substring(6);
System.out.println(s1);
//6.public String replace(CharSequence target,CharSequence replacement)
String name3 = "csl是最帅的,csl加油";
String s3 = name3.replace("csl", "陈太帅");
System.out.println(s3);
//7.public boolean contains(CharSequence s);
Boolean flag = name3.contains("csl");
System.out.println(flag);
//8.public boolean startsWiths(String perfix):判断是以什么开始
boolean flag1 = name3.startsWith("csl");
boolean flag2 = name3.startsWith("csl是最帅的");
boolean flag3 = name3.startsWith("csl是最帅的1");
System.out.println(flag1);
System.out.println(flag2);
System.out.println(flag3);
//9.public String[] split(String s):按照某个内容把字符串割成字符串数组返回
String name4 = "杨玉环,西施,貂蝉";
String[] s4 = name4.split(",");
for (int i = 0; i < s4.length; i++) {
System.out.println(s4[i]);
}
}
}
output:
10
中
------遍历字符串中的每个字符------
我
爱
你
中
国
C
h
i
n
a
我
爱
你
中
国
C
h
i
n
a
厉害了我的国
loveMyCountry
陈太帅是最帅的,陈太帅加油
true
true
true
false
杨玉环
西施
貂蝉
String 类的一些案例
案例一
- 需求:
- 随机产生一个5位的验证码,每位可能是数字、大写字母、小写字母。
- 分析:
- 定义一个String类型的变量存储a-z A-Z 0-9之间的全部字符。
- 循环5次,随机一个范围内的索引,获取对应的字符连接起来即可
package com.string;
import java.util.Random;
/**
练习题:使用String完成随机生成的5位验证码
*/
public class StringDemo04 {
public static void main(String[] args) {
//1.定义可能出现的字符信息
String datas = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
//2.循环5次,每次生成一个随机的索引,提取对应的字符连接起来即可
String code = "";
Random r = new Random();
for (int i = 0; i < 5; i++) {
//随机一个索引
int index = r.nextInt(datas.length());
char c = datas.charAt(index);
code += c;
}
//3.输出字符串即可
System.out.println(code);
}
}
案例二
- 需求:
- 模拟用户登录功能,最多只给三次机会
- 分析:
- 系统后台定义好正确的登录名称,密码。
- 使用循环控制3次,让用户输入正确的登录名和密码,判断是否登录成功,登录成功则不再进行登录;登录失败给出提示,并让用户继续登录。
package com.string;
import java.util.Scanner;
/*
模拟用户登录
*/
public class StringDemo05 {
public static void main(String[] args) {
//1.定义正确的用户名和密码
String okLoginName = "admin";
String okPassword = "123123";
Scanner sc = new Scanner(System.in);
//2.定义一个循环,循环3次,让用户登录
for (int i = 1; i <= 3 ; i++) {
System.out.println("请输入用户名:");
String loginName = sc.next();
System.out.println("请输入密码:");
String password = sc.next();
//3.判断是否登录成功!
if (okLoginName.equals(loginName)){
//4.用户名正确,再判断密码
if (okPassword.equals(password)){
System.out.println("登录成功!你可以随意浏览!");
break;
}else {
System.out.println("你的密码不正确,你还有"+(3-i)+"次机会!");
}
}else {
System.out.println("你输入的用户名不正确!你还有"+(3-i)+"次机会!");
}
}
}
}
output:
请输入用户名:
admin
请输入密码:
asgha
你的密码不正确,你还有2次机会!
请输入用户名:
adg
请输入密码:
ag
你输入的用户名不正确!你还有1次机会!
请输入用户名:
admin
请输入密码:
123123
登录成功!你可以随意浏览!
案例三
- 需求:
- 以字符串的形式从键盘接收一个手机号,将中间的四位号码屏蔽,最终效果为:188****5667
- 分析:
- 从键盘录入一个字符串,用Scanner实现
- 截取字符串前三位,截取字符串后四位
- 将截取后的两个字符串,中间加上****进行拼接,输出结果即可。
package com.string;
import java.util.Scanner;
/*
手机号码屏蔽
*/
public class StringDemo06 {
public static void main(String[] args) {
//1.定义一个Scanner对象
Scanner sc = new Scanner(System.in);
System.out.println("请输入手机号码:");
String phoneNumber = sc.next();
String s1 = phoneNumber.substring(0, 3);
String s2 = phoneNumber.substring(7);//直接从7截取到尾部
String s3 = s1 +"****"+s2;
System.out.println(s3);
}
}
output:
请输入手机号码:
1881112222
188****222