String字符串
String是一个类,属于数据类型中的引用类型
Java中一切使用双引号""引起来的内容,都是这个类的实例,称为字符串对象。
字符串在定义之后,值不可改变,是一个常量,实际是一个字符数组。
//这句话执行时,创建一个“Tom"字符串对象,将其地址保存到变量name中
String name = "Tom";
//这句话执行看似在改变字符串的值,实际是创建了一个新的"Jerry"字符串对象,将其地址保存到变量name中
name = "Jerry";
//以上两句,在内存中,会有两个字符串对象"Tom"和"Jerry",没有任何字符串发生了改变,只是name引用了不同的字符串地址
//字符串可以当做数组使用
String str1 = "hello";
//字符串对象实际是一个字符数组对象“包装”而来的
char[] list = {'h','e','l','l','o'};
String str2 = new String(list);
System.out.println(str1);
System.out.println(str2);
String类使用时注意
如果频繁的将一个String类型变量的值进行更改时,会创建很多字符串对象。效率低,浪费内存空间。
所以在频繁更改字符串时,不要使用String类变量
String str=""
//5万次的循环,就会有5万个字符串对象,但最终只会有一个字符串对象被str使用
for(int i=0;i<=50000;i++){
str+=i;
}
如果要频繁更改字符串的值,使用StringBuilder类或StringBuffer类
如何创建字符串对象
1.使用""赋值创建对象
2.通过构造方法创建
常用构造方法 | 说明 |
---|---|
String() | 创建一个空白字符串 |
String(String str) | 创建一个指定的字符串对象 |
String(char[] list) | 创建一个指定字符数组的字符串对象 |
String(byte[] list,String charsetName) | 按指定的编码格式创建一个指定字节数组的字符串对象 |
不同方式创建字符串的过程
使用""赋值的形式创建
public static void main(String[] args) {
//这句话执行时,先判断字符串常量池(缓冲区)中是否存在“ab”,不存在则创建,将其地址保存到str1变量中
String str1 = "ab";
//这句话执行时,先判断字符串常量池(缓冲区)中是否存在“ab”,已存在,不用创建,将其地址保存到str2变量中
String str2 = "ab";
//这句话执行时,+两端如果都是“”定义的字符串,拼接后再判断字符串常量池(缓冲区)中是否存在
// 拼接后的“ab”,依然存在,将其地址保存到str3变量中
String str3 = "a"+"b";
//以上三句话,只会在内存中的字符串常量池(缓冲区)中创建一个“ab”,分别引用给3个变量
System.out.println(str1==str2);
System.out.println(str1==str3);
}
可以使用jdk中自带的反编译工具javap对class文件进行反编译
在class文件所在目录下(项目的Out目录中),进入控制台,输入javap -c 字节码文件名.class
使用构造方法String(String str)创建
public static void main(String[] args) {
//这句话执行时的流程
//1.在字符串常量池中寻找“ab”,不存在,创建
//2.在堆中new String(),将常量池中的“ab”保存到new出来的区域
//3.将堆中new出来的地址保存到栈中变量str1中
String str1 = new String("ab");
//这句话执行时的流程
//1.在字符串常量池中寻找“ab”,存在,直接引用
//2.在堆中new String(),将常量池中的“ab”保存到new出来的区域
//3.将堆中new出来的地址保存到栈中变量str2中
String str2 = new String("ab");
//由于str1和str2是堆中的两个区域,所以结果为false
System.out.println(str1 == str2);
}
使用+拼接""和new出来的字符串创建对象
//在字符串常量池中创建"ab"
String str1 = "ab";
//1.创建StringBuilder对象
//2.在字符串常量池中创建"a"
//3.在字符串常量池中创建"b"
//4.创建String对象
//5.调用StringBuilder的append方法,将"a"和new String("b")拼接
String str2 = "a" + new String("b");//一共创建了"a","b",String,StringBuilder这四个对
象
//两个不同的地址
System.out.println(str1==str2);//false
总结
在使用字符串时,如果要比较值是否相同,不要使用判断,因为判断的是内存地址。
所以在比较字符串是否相同时,要使用String类重写equals方法进行判断
该方法判断原理为:将两个字符串用字符数组保存,逐个判断字符数组中的每一个字符,全部一致时返回true。
所以比较的是字面值,再使用equals方法时,通常将已知的非空字符串作为调用者。
username.equals("admin");//这样写,username变量可能为空,会抛出空指针异常
"admin".equals(username);//这样写能避免空指针异常
字符串类中的常用方法
方法名 | 返回值 | 作用 |
---|---|---|
length() | int | 得到字符串的长度 |
toLowerCase() | String | 转换为小写 |
toUpperCase() | String | 转换为大写 |
trim() | String | 去除首尾空 |
isEmpty() | boolean | 判断字符串是否是空白字符串 |
getBytes() | byte[] | 将字符串转换为字节数组 |
toCharArray() | char[] | 将字符串转换为字符数组 |
equalsIgnoreCase(String str) | boolean | 忽略大小写判断两个字符串是否相同 |
equals(String str) | boolean | 判断两个字符串是否相同 |
charAt(int index) | char | 得到字符串指定索引上的字符 |
indexOf(String str) | int | 得到某个子字符串第一次出现的索引,如果不存在,返回-1 |
lastIndexOf(String str) | int | 得到某个子字符串最后一次出现的索引,如果不存在,返回-1 |
contains(字符序列) | boolean | 判断某个字符串中是否存在指定子字符串 |
concat(String str) | String | 将参数字符串拼接到原字符串末尾 |
startsWith(String str) | boolean | 判断是否以指定字符串开头 |
endsWith(String str) | boolean | 判断是否以指定字符串结尾 |
substring(int begin) | String | 从指定索引开始截取至字符串末尾 |
substring(int begin,int end) | String | 截取[begin,end)区间内的字符串 |
split(String regex) | String | 按照指定字符串或正则表达式切分原字符串。如果指定内容不在末尾,n个指定字符能得到n+1个子串;如果指定内容在末尾,n个指定字符能得到n个子串 |
replace(char oldChar,char newChar) | String | 将原字符串中的所有指定字符替换为新字符 |
String.valueOf(参数) | String | 将任意参数转换为字符串,通常用于原始类型转换为字符串。 |
String.format(String 格式,Object… obj) | String | 根据指定格式转换参数。常用于将浮点数保留小数。如:String.format(“%4.2”,10.0/3)表示将计算结果四舍五入保留两位小数转换为字符串;如果最终数据所占不足4位,就在最前面补空格;如果最终数据够4位,就原样输出。 |
练习
- 接收一个身份证号码,输出这个人的年龄和性别(倒数第二位奇数为男,偶数为女)
package day1.com.hqyj.homeWork;
import java.lang.reflect.Type;
import java.util.Calendar;
import java.util.Scanner;
public class Test1 {
public static void main(String[] args) {
Calendar date = Calendar.getInstance();
String year = String.valueOf(date.get(Calendar.YEAR));
Scanner sc = new Scanner(System.in);
System.out.println("请输入您的身份证号");
String id = sc.next();
if(id.length() != 18){
System.out.println("输入错误!");
return;
}
//使用substring截取所需信息
String borth = id.substring(6,10);
//使用charAt获取指定索引的内容
if(id.charAt(16)%2==0){
System.out.println("您的性别为女");
}else{
System.out.println("您的性别为男");
}
/*
* 将字符串转换为数字
* Integer.parseInt(String str)
* */
int year1 =Integer.parseInt(year);
int borth1=Integer.parseInt(borth);
System.out.println("您的年龄为:"+(year1-borth1));
}
}
- 接收一个11位手机号码,使用替换中间4位。如13915863214,输出139***3214
package day1.com.hqyj.homeWork;
import com.sun.deploy.security.SandboxSecurity;
import java.util.Random;
import java.util.Scanner;
public class Work2 {
public static void main(String[] args) {
Scanner sc= new Scanner(System.in);
while (true) {
System.out.println("请输入您的号码");
String strNum = sc.next();
if (strNum.length() == 11) {
String n2 = strNum.substring(3, 7);
//如果使用replace会全部替换
// System.out.println(strNum.replace(n2, "****"));
System.out.println(strNum.replaceFirst(n2, "****"));
return;
} else {
System.out.println("号码输入有误");
}
}
}
}
- 接受一个字符串,输出其倒叙形式。如how are you,输出uoy era woh
package day1.com.hqyj.homeWork;
import java.util.Scanner;
public class Work3 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入");
String str = sc.nextLine();
//将原字符串转换为字符数组
char[] words = str.toCharArray();
//定义翻转后的字符数组
char[] reverseChars = new char[str.length()];
// 倒序遍历
for (int i = words.length-1; i >=0; i--) {
// char s =words.charAt(i);
//正向存储
reverseChars[words.length-i-1]=words[i];
}
//使用字符串的构造方法,将数组定义为字符串
String reverseStr = new String(reverseChars);
System.out.println(reverseStr);
}
}
- 接收一个网站的全域名,输出其顶级域名属于什么类型
- 顶级域名:www.baidu.com中,.com就是顶级域名
- .com商业网站,.edu教育网站,.gov政府网站,.org非营利性论坛
package day1.com.hqyj.homeWork;
import java.util.Scanner;
public class Work4 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入域名");
String name = sc.nextLine();
//截取.最后一次出现的位置
int n1 = name.lastIndexOf(".");
//从点最后一次出现的位置截取至末尾
String n2 = name.substring(n1);
if(".com".equals(n2)){
System.out.println("该网站是商业网站");
}else if(".edu".equals(n2)){
System.out.println("该网站是教育网站");
}else if(".gov".equals(n2)){
System.out.println("该网站是政府网站");
}else if(".org".equals(n2)){
System.out.println("该网站是非营利性网站");
}else{
System.out.println("其他");
}
}
}