字符串
基本概念
字符类型(char)是Java中的基本数据类型之一,字符是用单引号引住的单个符号。字符串(String)是用双引号引住的任意个字符,字符串其实就是字符组成的序列。字符串在开发中可以用来表示标题,名称,地址等。
char ch = 'T'; // 声明一个字符类型的变量ch,初始化为T
ch = '5';
ch = ',';
ch = '你';
// 字符串是字符组成的序列
String name = "pomelo";
// 文本块 """ 字符内容 """
String text = """
序号 姓名
1 张三
"snadnlasmkl"
""";
System.out.println(text);
字符串对象与字面量
字符串的声明
String 变量名 = "初始值";
String 变量名 = new String("初始值");
- 第一种形式使用双引号引住的字符串叫做字面量
- 第二种使用new运算符声明的字符串叫做字符串对象。【第二种形式并不常用,推荐使用第一种形式。】
字符串常用的API
API概述
API(全称是Application Program Interface 应用程序接口),说人话就是:别人写好的一些程序,给咱们程序员直接拿去调用。Java官方其实已经给我们写好了很多很多类,每一个类中又提供了一系列方法来解决
与这个类相关的问题。
- 比如String类,表示字符串,提供的方法全都是对字符串操作的。
像这样的类还有很多,Java把这些类是干什么用的、类中的每一个方法是什么含义,编写成了文档,我们把这个文档称之为API文档。
在编程开发中,经常需要对字符串进行各种操作,熟练掌握字符串的各种操作,对提高编程技巧很有帮助。要学习字符串的操作,首先要了解字符串的组成。字符串内部使用byte数组(JDK8之前是char数组)来保存字符串的内容,数组中的每一位存放一个字符,byte数组的长度也就是字符串的长度。
字符串中提供的常用操作方法,通过这些方法可以实现对字符串的连接、截取、替换、查找、比较等各种操作,更多操作查看API文档。
字符串的连接
字符串可以进行加法运算,作用是将两个字符串连接在一起,也可以将字符串与基本类型变量做加法运算,系统会先将基本类型转换为字符串型后进行连接操作。
在Java中将两个字符串连接在一起可以使用加号连接,也可以使用 concat() 方法连接。
字符串的比较
字符串也可以进行是否相等的比较,但不能直接使用 == 运算符,而是要使用equals() 方法进行比较。忽略大小写的比较 equalsIgnoreCase() 方法。
在Java中,equals()和==都是用于比较两个对象的操作,但它们有着不同的
含义和使用场景。
(1)==操作符用于比较两个对象的引用是否指向同一内存地址。如果两个对象的引用指向相同的内存地址,则它们是相等的。
(2)另一方面,equals()方法用于比较两个对象的值是否相等。默认情况下,equals()方法比较两个对象的引用是否相等,但可以通过重写该方法来实现自定义的相等比较逻辑。
(3)需要注意的是,对于基本类型的比较(如int、double等),==操作符比较的是它们的值,而不是引用。
字符串的长度
String类的 length() 方法可以获取字符串是由多少个字符构成的。
在数组中length属于数组的属性,而在字符串中length()是字符串的方法,注意进行区分。
字符串查找
indexOf()
判断传入字符串在原字符串中第一次出现的位置lasetIndexOf()
判断传入字符串在原字符串中最后一次出现的位置startsWith()
判断原字符串中是否以传入字符串开头endsWith()
判断原字符串中是否以传入字符串结尾
案例:
验证用户的email是否合法:从键盘上输入email,对email进行验证,合法的email的条件是:必须包含“@”和“.”;“@”必须在“.”的前面;“@”只能出现一次;不能以“@”开头;不能以“.”结尾
public class ExecString {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("请输入你的email:");
String str=sc.next();
if (str.indexOf(".")>str.indexOf("@")&&str.indexOf("@")==str.lastIndexOf("@")&&!str.startsWith("@")&&!str.endsWith(".")){
System.out.println("你填写的Email正确");
}else{
System.out.println("你的Email格式不正确!");
}
}
}
字符串去除空格
String str = " kaifamiao ";
System.out.println(str);
System.out.println(str.length());
// trim 去除两端空格
String strTrim = str.trim();
System.out.println("trim");
System.out.println(strTrim);
System.out.println(strTrim.length());
// strip 去除两端空格
String strStrip = str.strip();
System.out.println("strip");
System.out.println(strStrip);
System.out.println(strStrip.length());
// stripIndent 去除每一行的两端空格 去除前置最少得空格数量后面全部去掉
String strStripIndent = str.stripIndent();
System.out.println("stripIndent");
System.out.println(strStripIndent);
System.out.println(strStripIndent.length());
// stripLeading 去除前置空格
String strStripLeading = str.stripLeading();
System.out.println("stripLeading");
System.out.println(strStripLeading);
System.out.println(strStripLeading.length());
// stripTrailing 去除后置空格
String strStripTrailing = str.stripTrailing();
System.out.println("stripTrailing");
System.out.println(strStripTrailing);
System.out.println(strStripTrailing.length());
System.out.println("=========");
String string = " nihao \n test \n hello ";
System.out.println(string);
System.out.println(string.length());
String string2 = string.stripIndent();
System.out.println("======");
System.out.println(string2);
System.out.println(string2.length());
String string3 = string.stripTrailing();
System.out.println(string3);
System.out.println(string3.length());
String string4 = string.stripLeading();
System.out.println(string4);
System.out.println(string4.length());
String string5 = string.trim();
System.out.println(string5);
System.out.println(string5.length());
String string6 = string.strip();
System.out.println(string6);
System.out.println(string6.length());
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0wtJeTML-1693148835110)(https://gitee.com/wang-moumin/images/raw/master/images/image-20230823235006568.png)]
字符串内容替换
String类的 replace()
方法用于将字符串中指定的内容替换成其他内容。
字符串截取
String类的 subString(int,int) 方法用于字符串内容的截取,第一个参数是从第几位开始截取,第二个参数是截取到第几位,如果没有给定第二个参数,默认截取到最后一位。
练习
现有如下文本:“Java语言是面向对象的,Java语言是健壮的,Java语言是安全的,Java是高性能的,Java语言是跨平台的”。请编写程序,统计该文本中"Java"一词出现的次数。
public class subString {
public static void main(String[] args) {
String str=new String("Java语言是面向对象的,Java语言是健壮的,Java语言是安全的,Java是高性能的,Java语言是跨平台的。");
String str1="Java";
int count=countTimes(str,str1);
System.out.println("java共出现了"+count+"次");
}
public static int countTimes(String str,String str1){
int count = 0;
int index = str.indexOf(str1); // 第一次出现的下标
while (index >= 0) {
count++;
str = str.substring(index + str1.length());
index = str.indexOf(str1);
}
return count;
}
}
转义字符
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UIdmsF7o-1693148835111)(https://gitee.com/wang-moumin/images/raw/master/images/image-20230823235304711.png)]
字符串格式化
String类的 format() 方法用于创建格式化的字符串以及连接多个字符串对象。format方法定义是 format(String format, Object… args); 第一个参数是被格式化的字符串,第二个参数是替换格式符的字符串,第二个参数中的…表示方法可变参数,即参数的个数根据格式符的个数来确定。字符串格式化就是使用第二个可变参数中的值按照顺序替换第一个参数中的格式符。format方法的格式符定义如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E1EwOHVG-1693148835111)(https://gitee.com/wang-moumin/images/raw/master/images/image-20230823235347315.png)]
public static void main(String[] args) {
String str = String.format("见过,%s及%s", "晁天王", "众位头领");
System.out.println(str);
str = String.format("字母a的大写是:%c", 'A');
System.out.println(str);
str = String.format("3 > 7的结果是:%b", 3 > 7);
System.out.println(str);
str = String.format("100的一半是:%d", 100 / 2);
System.out.println(str);
// 使用printf()方法代替format方法来格式化字符串
System.out.printf("50元的书打8.5折扣是:%f 元", 50 * 0.85);
}
getBytes
使用平台的默认字符集将字符串编码为 byte 序列,并将结果存储到一个新的 byte 数组中。
char[] chs = {'让', '编', '程', '变', '简', '单'};
String str = new String(chs, 3, 4);
System.out.println(str);
// 用系统默认编码
System.out.println(Charset.defaultCharset());
// 自定义编码
Charset charset = Charset.forName("gbk");// gbk 编码对象
// charset = StandardCharsets.UTF_8;
// byte[] bytes = "原神".getBytes("gbk");
byte[] bytes = "原神".getBytes(charset);
System.out.println(Arrays.toString(bytes));
// 自定义编码
str = new String(bytes, charset);
System.out.println(str);
字符串是否为空
isBlank()
: 字符串中没有有效字符,结果为true
isEmpty()
:只要字符串的长度是0,结果就是true
replaceAll
和 replaceFirst
replaceAll
:替换所有满足pattern的内容为新内容
replaceFirst
: 替换第一次满足pattern的内容为新内容
contains
:字符串中是否有子串
String str = "kaifamiao1234开发喵123";
String pattern = "\\d{4}";//4个连续的数字
String replace = str.replace('a', 'A');
System.out.println(replace);
// replaceAll 替换所有满足pattern的内容为新内容
String kfm = str.replaceAll(pattern, "a");
// replaceFirst 替换第一次满足pattern的内容为新内容
String replaceFirst = str.replaceFirst(pattern, "a");
System.out.println(kfm);
System.out.println(replaceFirst);
// contains 字符串中是否有子串
System.out.println(str.contains("kfm"));
正则表达式
正则表达式(Regular Expression,简称Regex或RegExp)是一种字符串处理的工具,它用于匹配、查找、替换和提取文本中的模式。
正则表达式由一些特殊字符和普通字符组成,可以表示一类字符串的通用规律。例如,正则表达式\d{3}-\d{4}可以匹配形如"123-4567"的字符串,其中\d表示数字字符,{3}表示连续匹配三次,-表示匹配一个横线,\d{4}表示连续匹配四次数字字符。以下是一些常用的正则表达式规则:
普通字符
普通字符包括没有显式指定为元字符的所有可打印和不可打印字符。这包括所有大写和小写字母、所有数字、所有标点符号和一些其他符号。例如
特殊字符
所谓特殊字符,就是一些有特殊含义的字符,许多元字符要求在试图匹配它们时特别对待。若要匹配这些特殊字符,必须首先使字符"转义",即,将反斜杠字符\ 放在它们前面。下表列出了正则表达式中的特殊字符:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OLxdl7J1-1693148835112)(C:\Users\whm24\AppData\Roaming\Typora\typora-user-images\image-20230827174018349.png)]
非打印字符
非打印字符也可以是正则表达式的组成部分。下表列出了表示非打印字符的转义序列:
限定符
限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有 * 或 + 或 ? 或 {n} 或 {n,} 或 {n,m}共6种。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d8Mebf6k-1693148835112)(https://gitee.com/wang-moumin/images/raw/master/images/image-20230827175124703.png)]
定位符
定位符用来描述字符串或单词的边界,^ 和 $ 分别指字符串的开始与结束,\b 描述单词的前或后边界,\B 表示非单词边界。
正则表达式的定位符有:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cXuZl26V-1693148835113)(https://gitee.com/wang-moumin/images/raw/master/images/image-20230827175232436.png)]
以上是一些常用的正则表达式规则,可以通过它们来匹配、查找、替换和提取文本中的模式。需要根据具体需求选择合适的规则并进行组合。
1.限定符出现在范围表达式之后,* 和 + 限定符都是贪婪的,因为它们会尽可能多的匹配⽂字,只有在它们的后⾯加上⼀个 ? 就可以实现⾮贪婪或最⼩匹配。
2.不能将限定符与定位符⼀起使⽤。由于在紧靠换⾏或者单词边界的前⾯或后⾯不能有⼀个以上位置,因此不允许诸如 ^* 之类的表达式。若要匹配⼀⾏⽂本开始处的⽂本,请在正则表达式的开始使⽤ ^ 字符。
不要将 ^ 的这种⽤法与中括号表达式内的⽤法混淆。
3.⽤圆括号 () 将所有选择项括起来,相邻的选择项之间⽤ | 分隔。() 表⽰捕获分组,() 会把每个分组⾥的匹配的值保存起来, 多个匹配值可以通过数字 n 来查看(n 是⼀个数字,表⽰第 n 个捕获组的内容)。
4.^ 和 [^指定字符串] 之间的区别:^ 指的是匹配字符串开始的位置; [^指定字符串] 指的是除指定字符串以外的其他字符串。
在Java中,正则表达式的处理需要使用Java的正则表达式API,主要包括Pattern和Matcher两个类。Pattern类表示正则表达式的编译结果,Matcher类则用于在字符串中查找和匹配模式。以下是Java中常用的正则表达式方法:
Pattern.compile(String regex)
该方法用于将正则表达式编译成一个Pattern对象,其中regex是一个字符串类型的正则表达式。
public static void main(String[] args) {
String regex = "\\d+"; // 匹配数字
Pattern pattern = Pattern.compile(regex); // 将正则表达式编译成模式
String text = "hello 123 world";
Matcher matcher = pattern.matcher(text); // 创建匹配器对象
while (matcher.find()) {
// 输出匹配结果
System.out.println(text + "匹配结果是:" + matcher.group());
}
}
matcher.matches()
该方法用于判断给定字符串是否与正则表达式匹配,返回一个布尔值。
public static void main(String[] args) {
String regex = "\\d+"; // 匹配数字
Pattern pattern = Pattern.compile(regex); // 将正则表达式编译成模式
String text = "123456";
Matcher matcher = pattern.matcher(text); // 创建匹配器对象
boolean isMatched = matcher.matches(); // 尝试将整个输入序列与该模式匹配
System.out.println(isMatched); // 输出匹配结果,true
}
matcher.find()
该方法用于在给定字符串中查找匹配正则表达式的子序列,并返回一个布尔值。如果找到,则可以使用group()方法获取匹配的子序列。
public static void main(String[] args) {
Pattern p = Pattern.compile("\\d\\d\\d");
Matcher m = p.matcher("a123b");
System.out.println(m.find()); // 输出结果true
}
matcher.replaceAll(String replacement)
该方法用于在给定字符串中替换匹配正则表达式的子序列,其中replacement是一个字符串类型的替换字符串。
public static void main(String[] args) {
// 匹配数字
String regex = "\\d+";
// 将正则表达式编译成模式
Pattern pattern = Pattern.compile(regex);
String text = "hello 123 world 456";
// 创建匹配器对象
Matcher matcher = pattern.matcher(text);
// 将匹配的子序列替换为"###"
String replacedText = matcher.replaceAll("###");
// 输出替换后的结果字符串 hello ### world ###
System.out.println(replacedText);
}
除了上述方法之外,Java还提供了许多其他的正则表达式处理方法,例如通过正则表达式分割字符串、在字符串中查找多个匹配等。需要根据具体需求选择合适的方法。
练习
用户登录
接下来给大家做一个案例,使用字符串的功能完成登录案例。案例需求如下:
需求
系统默认的登录名和密码是kfm/123456,请在控制台开发一个登录界面,接受用户输入的登录名和密码,判断用户是否登录成功,登录成功后展示:“欢迎进入系统!”,即可停止程序。(最多三次登录机会)
分析一下完成案例的步骤:
1.首先,从登录界面上可以得出,需要让用户输入登录名和密码
2.设计一个登录方法,对用户名和密码进行校验
3.调用登录方法,根据方法的返回结果,判断登录是否成功。
4.如果登录失败,循环登录3次,结束循环;如果登录成功,跳出循环;
代码实现:
import java.util.Scanner;
public class Work01 {
static Scanner sc=new Scanner(System.in);
public static void main(String[] args) {
//登录功能,最多三次机会
System.out.println("请输入你的用户名:");
String name=sc.next();
System.out.println("请输入你的密码:");
String password=sc.next();
login(name,password);
}
public static void login(String Username,String Userpassword){
String name="kfm";
String password="123456";
for (int i = 3; i >=0 ; i--) {
if(name.equals(Username)&&password.equals(Userpassword)){
System.out.println("欢迎进入系统!");
break;
} else if(i>1){
System.out.println("登陆失败!");
System.out.printf("你还有%d次机会",i-1);
System.out.println();
System.out.println("请重新输入用户名:");
Username=sc.next();
System.out.println("请重新输入密码:");
Userpassword=sc.next();
}else if(i==1){
System.out.println("登录失败!");
}
}
}
}
随机产生验证码
接下来学习一个再工作中也比较常见的案例,使用String来开发验证码。需求如下:
需求:
实现随机产生验证码,验证码的每位可能是数字、大写字母、小写字母。
根据需求分析,步骤如下:
1.首先,设计一个方法,该方法接收一个整型参数,最终要返回对应位数的随机验证码。
2.方法内定义2个字符串变量:
1个用来记住生成的验证码,1个用来记住要用到的全部字符。
3.定义for循环控制生成多少位随机字符
4.每次得到一个字符范围内的随机索引
5.根据索引提取该字符,把该字符交给code变量连接起
6.循环结束后,在循环外返回code即可。
7.在主方法中调用生成验证码的方法
代码实现:
import java.util.Random;
import java.util.Scanner;
public class Work02 {
//随机验证码
public static void main(String[] args) {
System.out.println("请输入你想要的验证码位数");
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
System.out.println("随机产生的验证码为");
verify(n);
}
public static void verify(int n) {
Random r = new Random();
char num=0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < 3; j++) {
int shunxv=r.nextInt(3)+1;
if(shunxv==1){
num= (char) (r.nextInt(26)+65);
} else if (shunxv==2) {
num= (char) (r.nextInt(26)+97);
} else if (shunxv==3) {
num= (char) (r.nextInt(10)+48);
}
}
System.out.print(num);
}
}
}
以后遇到对字符串进行操作的需求,优先找String类有没有提供对应的方法。
字符串处理
在实际应用中,我们经常会遇到字符串类型与基本类型的转换操作。在Web开发中,Java程序从界面上获取数据都是以String类型获取的,例如学生成绩80在Web中是以String类型获取的,如果成绩需要参与算术运算,那么就需要将String类型的成绩转换成int类型后才能参与算术运算。
包装类介绍
在Java中,基本数据类型(如int、double、boolean等)与对象类型是两个不同的概念。为了使基本数据类型也具备面向对象的特性,Java提供了包装类(Wrapper Class)。
包装类是一种特殊的类,用于将基本数据类型封装成对象。Java中提供了8种包装类,分别对应8种基本数据类型,它们分别是:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-M25pe61J-1693148835113)(https://gitee.com/wang-moumin/images/raw/master/images/image-20230827212259285.png)]
包装类提供了许多有用的方法,例如将字符串转换为对应的基本数据类型,将基本数据类型转换为字符串,比较两个包装对象的大小等等。此外,包装类也可以作为一种数据类型,在泛型编程、反射等方面具有重要的作用。
构造方法(JDK9之后过时)
Integer构造方法名:Integer(int value)、Integer(String s)。Byte、Short、Long、Float、Double、Boolean的构造方法和Integer的构造方法类似。
Character只有一个构造方法:Character(char value)
Float比Integer多一个:Float(double value)
public static void main(String[] args) {
// "123"
// Java9之后不建议使用这个构造方法了。出现横线表示已过时。
// 将数字100转换成Integer包装类型(int --> Integer)
Integer x = new Integer(100);
System.out.println(x); // 100
// 将String类型的数字,转换成Integer包装类型。(String --> Integer)
Integer y = new Integer("123");
System.out.println(y); // 123
// double -->Double
Double d = new Double(1.23);
System.out.println(d); // 1.23
// String --> Double
Double e = new Double("3.14");
System.out.println(e); // 3.14
}
包装类常量
包装类中都有两个常量:MAX_VALUE、MIN_VALUE,分别表示最大值和最小值。
public static void main(String[] args) {
// 通过访问包装类的常量,来获取最大值和最小值
System.out.println("int的最大值:" + Integer.MAX_VALUE); // 2147483647
System.out.println("int的最小值:" + Integer.MIN_VALUE); // -2147483648
System.out.println("byte的最大值:" + Byte.MAX_VALUE); // 127
System.out.println("byte的最小值:" + Byte.MIN_VALUE); // -128
System.out.println("double的最大值:" + Double.MAX_VALUE); // 1.7976931348623157E308
System.out.println("double的最小值:" + Double.MIN_VALUE); // 4.9E-324
}
装箱/拆箱
Java中的拆箱和装箱是指基本数据类型和对应的包装类之间的转换。Java中的包装类提供了一些方法来完成拆箱和装箱的操作,这些方法包括:
**装箱:**将基本数据类型转换为对应的包装类对象,可以使用包装类的构造方法或静态方法valueOf()来完成。
**拆箱:**将包装类对象转换为对应的基本数据类型,可以使用包装类提供的xxxValue()方法来完成。
public static void main(String[] args) {
// 装箱:将int类型转换为Integer类型
int i = 100;
Integer integerObj = new Integer(i);
Integer integerObj2 = Integer.valueOf(i);
// 拆箱:将Integer类型转换为int类型
Integer integerObj3 = new Integer(200);
int j = integerObj3.intValue();
int k = integerObj3; // 自动拆箱
}
通过包装类的构造方法和valueOf()方法将int类型的变量i装箱为Integer类型的对象。然后通过Integer对象的intValue()方法将其拆箱为int类型。除此之外,在JDK 5及以上版本中,还支持自动拆箱和装箱的操作,即在需要使用基本数据类型的地方,可以直接使用对应的包装类对象,或者在需要使用包装类对象的地方,也可以直接使用基本数据类型的变量。
自动拆箱/自动装箱(JDK5新特性)
当基础类型与它们的包装类有如下几种情况时,编译器会自动帮我们进行装箱或拆箱:
- 进⾏ = 赋值操作(装箱或拆箱)
- 进⾏+,-,*,/混合运算 (拆箱)
- 进⾏>,<,==⽐较运算(拆箱)
- 调⽤equals进⾏⽐较(装箱)
- ArrayList,HashMap等集合类添加基础类型数据时(装箱)
public static void main(String[] args) {
int a = 100;
Integer b = 100;
System.out.println(a == b); // true
Integer c = 100;
Integer d = 100;
System.out.println(c == d); // true
Integer num1 = new Integer(100);
Integer num2 = new Integer(100);
System.out.println(num1 == num2); // false
c = 200;
d = 200;
System.out.println(c == d); // false
}
// 基础类型a与包装类b进行==比较,这时b会拆箱,直接比较值
// 包装类型c和d进行比较的时候比较的是地址
在Integer类的 valueOf()
方法中
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
可以看到,这里的实现并不是简单的new Integer,而是用IntegerCache做一个cache,cache的range是可以配置的,默认Integer cache 的下限是-128,上限默认127,可以配置,所以到这里就清楚了,我们上面当赋值100给Integer时,刚好在这个range内,所以从cache中取对应的Integer并返回,所以二次返回的是同一个对象,所以比较是相等的,当赋值200给Integer时,不在cache 的范围内,所以会new Integer并返回,当然比较的结果是不相等的。
Integer方法
Byte、Short、Long、Float、Double、Boolean照葫芦画瓢,方法差不多相同。
public static void main(String[] args) {
Integer d = Integer.decode("123");
System.out.println(d); // 123
Integer a = 100;
Integer b = 100;
System.out.println(Integer.compare(a, b)); // 0
System.out.println(Integer.compare(-a, b)); // -1
System.out.println(Integer.compare(a, -b)); // 1
System.out.println(a.equals(b)); // true
int i = Integer.parseInt("123");
System.out.println(i); // 123
System.out.println(Integer.signum(-123)); // -1
System.out.println(Integer.signum(123)); // 1
System.out.println(Integer.signum(0)); // 0
System.out.println(Integer.toBinaryString(10)); // 1010
System.out.println(Integer.toOctalString(10)); // 12
System.out.println(Integer.toHexString(10)); // a
String s = Integer.toString(123);
System.out.println(s); // 123
Integer int1 = Integer.valueOf("123");
System.out.println(int1); // 123
}
Character方法
public static void main(String[] args) {
Character c = 'a';
char res1 = c.charValue();
System.out.println(res1); // a
Character a = 'a';
Character b = 'b';
System.out.println(a.compareTo(b));
System.out.println(a.equals(b));
System.out.println(Character.isDigit('1'));
System.out.println(Character.isLetter('a'));
System.out.println(Character.isLetterOrDigit('1'));
System.out.println(Character.isLetterOrDigit('a'));
System.out.println(Character.isLowerCase('a'));
System.out.println(Character.isUpperCase('A'));
System.out.println(Character.isSpaceChar(' '));
System.out.println(c.toString());
System.out.println(Character.valueOf('c'));
}
String类型转换成基本类型
将字符串类型转换为基本类型,需要使用基本类型的包装类。 String 的 valueOf() 将基本数据类型转换成字符串
public static void main(String[] args) {
String employeeName = "喵星人";
String isMarried = "false"; // 是否已婚
String gender = "M"; // 性别
String baseSalary = "7000"; // 基本工资
String basicBonus = "300"; // 基础奖金
String basicBonusScore = "0.85"; // 基础奖金考核得分
String performanceBonus = "400"; // 考核奖金
String performanceBonusScore = "0.9"; // 考核奖金得分
String attendanceAllowance = "100"; // 全勤补助
boolean isMarriedBoolean = Boolean.parseBoolean(isMarried);
char genderChar = gender.charAt(0);
int baseSalaryInt = Integer.parseInt(baseSalary);
short basicBonusShort = Short.parseShort(basicBonus);
float basicBonusScoreFloat = Float.parseFloat(basicBonusScore);
long performanceBonusLong = Long.parseLong(performanceBonus);
double performanceBonusScoreDouble = Double.parseDouble(performanceBonusScore);
byte attendanceAllowanceByte = Byte.parseByte(attendanceAllowance);
// 计算总收入
double totalIncome = baseSalaryInt + basicBonusShort * basicBonusScoreFloat +
performanceBonusLong * performanceBonusScoreDouble +
attendanceAllowanceByte;
System.out.println(employeeName + ",性别(" + genderChar + ")" +
",婚否(" + isMarriedBoolean + "),总工资=" + totalIncome);
}
- 基本类型中除了char类型以外,其它7种基本类型使⽤各⾃的包装类调⽤parseXxx()⽅法将String类型转换为基本类型。
- char类型的转换可以通过String类的charAt(index)⽅法完成。
基本类型转换为String类型
String类型的数据参与算术运算时,需要将String类型转换为基本类型,基本类型的数据在界面上显示时需要将数据转换成String类型后输出在界面上。
八种基本类型的数据转换成String类型有两种方法。
- 通过“+”将基本类型与String类型连接,将基本类型转换成String类型。
- 通过String.valueOf(基本类型数据)⽅法将基本类型转换成String类型。
Math类
Math类是Java中的一个内置类,位于java.lang包中。它提供了许多用于执行数学运算的静态方法和常量。Math类中的方法都是以静态方式调用,无需创建Math类的实例。
以下是Math类的一些常用方法和常量:
常量有两个:
- Math.PI :表⽰π(圆周率)的近似值。
- Math.E :表⽰⾃然对数的底数e的近似值。
以下是一个使用Math类的示例:
public static void main(String[] args) {
int num = -5;
int absNum = Math.abs(num);
System.out.println(absNum); // 5
double n = 16.0;
double sqrtNum = Math.sqrt(n);
System.out.println(sqrtNum); // 4.0
double base = 2.0;
double exponent = 3.0;
double result = Math.pow(base, exponent);
System.out.println(result); // 8.0
int num1 = 10;
int num2 = 7;
int maxNum = Math.max(num1, num2);
System.out.println(maxNum); // 10
int minNum = Math.min(num1, num2);
System.out.println(minNum); // 7
double n1 = 4.2;
double ceilNum = Math.ceil(n1);
System.out.println(ceilNum); // 5.0
double floorNum = Math.floor(n1);
System.out.println(floorNum); // 4.0
double n2 = 4.6;
long roundedNum = Math.round(num);
System.out.println(roundedNum); // 5
double randomNum = Math.random();
System.out.println(randomNum); // 0.0~1.0
}
**请注意,Math类的方法都是静态的,可以直接通过类名调用,无需创建Math类的实例。Math类提供了很****多其他的数学运算方法,如三角函数、对数函数、指数函数等。你可以根据需要查阅API官方文档或其他相关资源来了解更多Math类的方法和用法。
String的注意事项
在Java中,字符串是不可变的,这意味着一旦创建了一个字符串对象,它的内容就不能被修改。当你对一个字符串进行操作时(比如连接、替换、截取等),实际上是创建了一个新的字符串对象,而原始的字符串对象保持不变。
这种不可变性有以下几个关键特点:
(1)字符串对象是不可修改的: 一旦创建了一个字符串对象,就无法更改它的内容。例如,如果你有一个字符串“hello”,你无法直接修改内存里面存储的值“help”,而是在内存中重新产生一个新的字符串对象来表示“help”。
(2)线程安全: 由于字符串是不可变的,多个线程可以同时访问和共享相同的字符串对象,而不会出现并发修改的问题。这使得字符串在多线程环境中更安全。
(3)字符串池: Java中的字符串常量池(String Pool)是字符串不可变性的一个体现。当你创建一个字符串常量时,JVM会首先检查字符串常量池是否已经存在相同内容的字符串,如果存在,则直接返回对这个已存在字符串的引用,而不会重新创建一个新的对象。这样可以节省内存空间并提高性能。
(4)安全性: 字符串不可变性确保字符串对象在被传递给其他方法时,不会被修改,从而避免了在传递参数时意外修改字符串内容的情况。
字符串不可变性的一个常见实例是使用字符串连接操作符(“+”)来拼接字符串。
在这个例子中,通过字符串连接操作符连接str1和str2,实际上创建了一个新的字符串对象,而原始的str1和str2保持不变。
总的来说,字符串不可变性在Java中是一个重要的概念,它带来了安全性、线程安全性和性能优化等方面的好处。因此,当需要频繁对字符串进行操作时,最好使用StringBuilder或StringBuffer类,它们提供了可变的字符串操作。但在不需要频繁修改字符串的情况下,使用不可变的字符串可以带来更多的好处。
把字符串原理性的内容,就当做注意事项来学习一下。
注意事项1:String类的对象是不可变的对象
我们先看一段代码,分析这段代码的结果
public static void main(String[] args) {
String name = "开发喵";
name += "程序员";
name += "喵喵";
System.out.println(name);
}
下面我们就解释一下,String是不可变对象到底是什么含义。
需要注意的是:只要是以 “” 方式写出的字符串对象,会在堆内存中的字符串常量池中存储。
执行第一句话时,会在堆内存的常量池中,创建一个字符串对象 “开发喵” ,然后把“开发喵” 的地址赋值给 String name
当执行第二句话时,又会再堆内存的常量池中创建一个字符串 “程序员” ,和 “开发喵” 拼接,拼接之后还会产生一个新的字符串对象 ”开发喵程序员“ ,然后将新产生的“开发喵程序员” 对象的地址赋值给 String name 变量。
此时你会发现,之前创建的字符串对象 “开发喵” 内容确实是没有改变的。所以说String的对象是不可变的。
注意事项2:字符串字面量和new出来字符串的区别
-
只要是以 “…” 方式写出的字符串对象,会存储到字符串常量池,且相同内容的字符串只存储一份。
-
但通过 new 方式创建字符串对象,每new一次都会产生一个新的对象放在堆内存中。
public static void main(String[] args) {
String a = "a";
String b = "b";
String c = "ab";
String d = "a" + "b";
String e = a + "b";
String f = "a" + b;
String g = a + b;
String h = new String("ab");
System.out.println(c == d); // true
System.out.println(c == e); // false
System.out.println(c == f); // false
System.out.println(c == g); // false
System.out.println(c == h); // false
System.out.println("-------------------");
System.out.println(d == e); // false
System.out.println(e == f); // fasle
System.out.println(e == g); // fasle
System.out.println(f == g); // false
// String j = h.intern();
// System.out.println(j == c);
}
请编写程序,由键盘录入一个字符串,统计字符串中英文字母和数字分别有多少个。
比如:Hello12345World中字母:10个,数字:5个。
public class ToCharArray {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("请输入一个字符串:");
String str=sc.next();
geShu(str);
}
public static void geShu(String str){
char[] s1=str.toCharArray();
int count=0;
int count2=0;
for(char s:s1){
if(s>'a'&&s<'z'||s>'A'&&s<'Z'){
count++;
}
if (s>='0'&&s<='9'){
count2++;
}
}
System.out.printf("字母的个数是 %d个",count);
System.out.println();
System.out.printf("数字的个数是 %d个",count2);
}
}
总结一下,字符串的注意事项。
- String是不可变字符串对象
- 只要是以"…"方式写出的字符串对象,会存储到字符串常量池,且相同内容的字符串只存储一份;
- 但通过new方式创建字符串对象,每new一次都会产生一个新的对象放在堆内存中。
字符串变量
StringBuffer类
StringBuffer类是Java中一个可变的字符串类,它提供了对字符串进行修改的方法。与String类不同,StringBuffer类的对象可以修改,添加和删除它们包含的字符序列。
StringBuffer类是线程安全的,因此它的所有方法都是同步的。这意味着当一个线程访问一个StringBuffer对象时,其他线程必须等待,直到该线程完成其操作。这使得StringBuffer类在多线程环境中非常有用。
StringBuffer类有多个构造方法,可以根据不同的需求选择合适的构造方法来创建对象。以下是StringBuffer类的
常见构造方法:
- StringBuffer(): 创建一个空的StringBuffer对象,初始容量为默认值(16个字符)。
- StringBuffer(int capacity): 创建一个空的StringBuffer对象,并指定初始容量。初始容量是指内部字符缓冲区的初始大小,用于存储字符串内容。
- StringBuffer(String str): 创建一个包含指定字符串的StringBuffer对象。初始容量将被设置为字符串的长度加上默认的容量增量(默认为16)。
- StringBuffer(CharSequence seq): 创建一个包含指定字符序列的StringBuffer对象。CharSequence是一个接口,可以是String、StringBuilder或其他实现CharSequence接口的类的实例。
使用示例
public static void main(String[] args) {
// 创建一个空的StringBuffer对象
StringBuffer sb1 = new StringBuffer();
// 创建一个初始容量为20的StringBuffer对象
StringBuffer sb2 = new StringBuffer(20);
// 创建一个包含字符串"Hello"的StringBuffer对象
StringBuffer sb3 = new StringBuffer("Hello");
// 创建一个包含StringBuilder对象内容的StringBuffer对象
StringBuffer sb4 = new StringBuffer(new StringBuilder("World"));
}
以下是一些常用的StringBuffer方法:
以下是使用StringBuffer类的示例:
public static void main(String[] args) {
// 创建一个空的StringBuffer对象
StringBuffer sb = new StringBuffer();
sb.append("Hello");
sb.insert(5, " World");
sb.deleteCharAt(10);
sb.reverse();
System.out.println(sb.toString());
}
StringBuffer类在Java 5中被StringBuilder类取代。StringBuilder类与StringBuffer类相似,但不是线程安全的。在单线程环境下,建议使用StringBuilder类而不是StringBuffer类,因为StringBuilder类的执行速度更快。
StringBuilder类
StringBuilder是Java中的一个类,它提供了一种可变的字符串缓冲区,可以动态地添加、修改和删除字符串内容。StringBuilder类是可变的,这意味着它的长度和内容可以随着需要而变化,而不必创建新的对象。
StringBuilder类提供了许多方法,例如append()、insert()、delete()、replace()等,这些方法可以在字符串缓冲区中添加、插入、删除或替换字符或子字符串。
下面是一些StringBuilder类的常用方法:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MBS68dV8-1693148835116)(https://gitee.com/wang-moumin/images/raw/master/images/image-20230827215412339.png)]
以下是一个使用StringBuilder类的示例:
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append(" ");
sb.append("World");
String result = sb.toString();
System.out.println(result); // Hello World
}