Java中的String类

Java中的String类,第1张

文章目录
  • String类
    • 认识String类
      • 创建字符串
      • 使用字符串字面量创建
      • 字符串比较
      • 关于字符串常量池
      • 手工入池方法
      • 使用构造方法创建
      • 理解字符串的不可变性
      • StringBuilder
        • 两个类之间的相互转换
        • append添加方法
        • reverse翻转方法
        • delete删除方法
        • insert插入方法
      • 字符和字符串的相互转换
      • isNumber方法
      • 字节和字符串相互转换
      • String类的一些常用方法
        • 字符串替换
        • 字符串拆分
        • 字符串查找
        • 字符串截取

String类 认识String类

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ongCXufY-1652504566846)(E:\桌面\String.png)]

在Java中String这个类是使用final修饰的

这说明String类是无法被继承的,这样的好处就是任何人使用的String都是一样的,不会拓展出多个版本,而且其类中成员属性也几乎都设计成了private final,这样String就被设计成了一个不变的类,这样有助于共享,提高性能

创建字符串

创建字符串的方式有四种

方式一:直接赋值

Sting str = “hello world”;

方式二:通过构造方法产生对象

String str = new String(“hello world”);

方式三:通过字符数组产生对象

char[] date = new char[]{‘a’,‘b’,‘c’};

Sting str = new String (date);

方法四:通过String的静态方法valueOf(任意数据类型) -->转为字符串

String str = String.valueOf(10)

String str = "hello world";
String str2 = new String("hello world");
char[] date = new char[]{'a','b','c'};
String str3 = new String(date);
String str4 = String.valueOf(10);
使用字符串字面量创建

字面量:直接写出来的数值就称之为字面量

10 -> int 字面量

10.1 -> double 字面量

true -> boolean 字面量

“abc” -> String 字面量 —>他就是一个字符串的对象

String是引用数据类型

//2.字面量
//这个hello world是String类的一个对象
String str = "hello world";
//让str1指向了str指向的"hello world";
String str1 = str;
//这时就是又创建了一个新的对象,让str1指向"Hello World"; 并不会对str造成影响
str1 = "Hello World";
System.out.println(str);
//打印结果
hello world

这就是让str1 = str时的内存情况,而若此时str1 = "Hello world"则是下图的情况

由于String是引用数据类型,若此时采用 "==" 来进行比较的话,比较的就是两个引用的地址,而不是其保存的内容,而引用数据类型若想要进行比较则需要采用equals方法来进行比较

字符串比较
//3.字符串比较
String str1 = new String("hello");
String str2 = new String("hello");
//比较的是地址 true
System.out.println(str1 == str2);
str2 = "Hello";
//equals方法比较的是内容 false
System.out.println(str1.equals(str2));
//不区分大小写的equals ---> equalsIgnoreCase true
System.out.println(str1.equalsIgnoreCase(str2));

//而使用compareTo比较,比较的是字符串ASCII码值的大小关系
String str1 = "abc";
String str2 = "Abc";
System.out.println(str1.compareTo(str2)); //打印结果32

要比较引用数据类型的内容,必须采用equals方法进行比较

这里有一点注意事项,就是涉及到用户使用的时候

//4.涉及到用户使用
String userName = null;
//方法一
System.out.println(userName.equals("hello"));
//方法二
//推荐使用这种写法,避免空指针异常
System.out.println("hello".equals(userName));

推荐使用的是方法二,这样能避免空指针异常,"hello"字符串字面量,本质上是一个String对象,所以可以调用equalsString对象的方法

关于字符串常量池
//5.字符串常量池
String str1 = "hello";
String str2 = "hello";
String str3 = "hello";
System.out.println(str1 == str2);   //true
System.out.println(str2 == str3);   //true
//说明str1、str2、str3指向的都是指向同一个字符串
//当使用赋值法,产生字符串对象时,JVM会维护一个字符串的常量池,若该对象还未存在
//则会产生一个新的字符串对象,若此时继续使用直接赋值法产生对象,若JVM发现该对象在常量池中已经存在
//则不会再产生新的对象,而是复用已有对象

从上面利用"=="比较打印的结果,我们就能发现,str1、str2、str3的地址是同一个地址,这就是涉及到常量池,当产生第一个对象的时候,会在常量池中存储,之后若创建相同的字符串对象,则是直接复用在常量池中的已有对象。

为什么不开辟新的空间存储呢?

String类设计使用的是共享设计模式

JVM底层会自动维护一个字符串常量池

  • 如果现在采用了直接赋值的模式进行String类的对象实例化 *** 作,那么该实例化对象(字符串内容)将自动保存 到这个对象池之中.
  • 如果下次继续使用直接赋值的模式声明String类对象,此时对象池之中如若有指定内容,将直接进行引用
  • 如若没有,则开辟新的字符串对象而后将其保存在对象池之中以供下次使用
手工入池方法

手工入池方法:String类提供的intern方法

@NotNull
public native String intern();

调用intern方法会将当前字符串引用指向的对象保存到字符串常量池中

两种情况

1.若当前常量池中已经存在了该对象,则不再产生新的对象,返回常量池中的对象

2.若当前常量池中不存在该对象,则将该对象入池,返回入池后的地址

String str1 = new String("hello");
//方法有返回值没接收 若改成str1 = str1.intern();打印的则是true
str1.intern(); 
String str2 = "hello";
System.out.println(str1 == str2);   
//打印结果
false
char[] date = new char[]{'a','b','c'};
//此时传入的并不是字面量而是 数组date
String str1 = new String(date);
str1.intern();
String str2 = "abc";
System.out.println(str1 == str2);
//打印结果
true
使用构造方法创建
String str1 = new String("hello");

这样使用String的构造方法创建字符串,会产生两个对象,因为此时的”hello“本身就是一个对象,而后面又new开辟新的空间创建对象,

对比字面量和构造方法创建字符串,推荐使用的是直接使用字面量直接赋值的方法创建String对象。

理解字符串的不可变性

字符串的不可变性

所谓的字符串不可变指的是字符串对象的内容不可变,而不是字符串引用不可变

那为什么字符串的对象无法修改内容而其他类的对象能修改内容

字符串是一个数组 在String类中保存是

private final byte[] value;

这个value数组是被private修饰,且String类没有提供settergetter方法,我们根本就无法访问到这个value数组,所以也就无法更改

StringBuilder

如何修改字符串的内容

1.在运行时通过反射破坏value数组的封装

2.更换使用StringBuilder或者StringBuffer类–>这和String已经不是一个类型了,这是另外两个类

public static void main(Sreing[] args){
StringBuilder sb = new StringBuilder();
sb.append("hello");
sb.append("world");
sb.append("!!!");
System.out.println(sb);
//打印结果
helloworld!!! 

关于SringBulider类的具体使用:

StringBuilder类和String类是两个独立的类

StringBuilder就是为了解决字符串的拼接问题产生的

因为String的对象无法修改内容,为了方便字符串的拼接 *** 作,产生了StringBuilder类,StringBuilder类的对象是可以修改内容的

两个类之间的相互转换

StringBuilder 转换成 String类 只需要调用toString方法就能转换

StringBuilder sb = new StringBuilder();
String str = sb.toString();
append添加方法

String 转换成 StringBuilder 可以使用 StringBuilder的构造方法 或者 append方法

StringBuilder sb = new StringBuilder("hello");
sb.append("world")

StringBuilder还有其他的方法

reverse翻转方法
StringBuilder sb = new StringBuilder("hello");
sb.append("world")
sb.reverse();
System.out.println(sb);
//打印结果
dlrowolleh
delete删除方法
StringBuilder sb = new StringBuilder("hello");
sb.append("world")
sb.delete(5,10)	//删除索引左闭右开区间
System.out.println(sb);
//打印结果
hello
insert插入方法

insert(int start,各种数据类型)

将新元素插入在start索引位置上

StringBuilder sb = new StringBuilder("hello");
sb.insert(4,10);
System.out.println(sb);
//打印结果
hell10o

也是基本的增删改查的 *** 作

常见面试题

请解释StringStringBuilderStringBuffer的区别

  1. String的对象无法修改,StringBuilderStringBuffer的对象内容可以修改
  2. StringBuffer是线程安全的 *** 作,性能较差;StringBuilder是线程不安全,性能较高
字符和字符串的相互转换
char[] ch = new char[]{'a','b','c'};
//利用String的构造方法 将字符转换为字符串
String str1 = new String(ch);   
//打印结果abc
//另外一种构造方法
//表示转换部分字符数组 offset表示开始的索引 count表示转换的个数
String str2 = new String(ch,1,2);
//打印结果 bc
//取得指定索引的字符
String str = "hello";
System.out.println(str.charAt(1));//打印结果 e
//将字符串转换为字符数组
String str = "hello";
char[] ch = str.toCharArray();
ch[0] = 'H';
System.out.println(str);    
//打印结果 hello
System.out.println(ch);     
//打印结果 Hello
isNumber方法

判断一直字符串是否是纯数字

//如何判断一个字符串是否为纯数字字符
String str1 = "123";
String str2 = "123a";
System.out.println(isNumber(str1));   //打印结果 true
System.out.println(isNumber(str2));   //打印结果 false

isNumber方法的实现

public static boolean isNumber(java.lang.String str) {
        char[] ch = str.toCharArray();
        for (char c: ch) {
            if(c < '0' || c > '9'){
                return false;
            }
//            //这个char的包装类 判断字符c是否是数字
//            if(!Character.isDigit(c)){
//                return false;
//            }
            //两个if是一样的结果
        }
        return true;
    }
字节和字符串相互转换
//字符串和字节的相互转换
byte[] date = new byte[]{97,98,99};
//使用String的构造方法 将字节转换为字符串
String str = new String(date);
System.out.println(str);
//打印结果
abc
String str = "你好中国";
byte[] date1 = str.getBytes();
byte[] date2 = str.getBytes("gbk");
String类的一些常用方法 字符串替换
String str = "hello world";
//将str字符串所有字符"l"改为"_"
System.out.println(str.replaceAll("l","_"));//打印结果he__o wor_d
//将str字符串第一个字符"l"改为"_"
System.out.println(str.replaceFirst("l","_"));//打印结果he_lo world
//这时并不会改变原来的字符串str,只有StringBuilder才能改变字符串
//String类提供的所有方法都不能更改字符串
System.out.println(str);   //打印结果 hello world
字符串拆分
String str = "Hello World Hello Java";
//将字符串按照" "拆分
String[] date1 = str.split(" ");
System.out.println(Arrays.toString(date1));      //打印结果[Hello, World, Hello, Java]
//依然是将字符串按照" "拆分,但显示字符串个数为2个
String[] date2 = str.split(" ",2);
System.out.println(Arrays.toString(date2));      //打印结果[Hello, World Hello Java]
//注意事项1
String str = "198.168.1.1";
String[] date1 = str.split(".");
System.out.println(Arrays.toString(date1));		//打印结果[]
//若出现打印结果为空[] 一般就是
//你的这个格式是个特殊字符需要转义处理"\"
String[] date2 = str.split("\.");
System.out.println(Arrays.toString(date2));
//打印结果[198, 168, 1, 1]

//注意事项2
String str = "198.168.1.1";
String[] date1 = str.split("-");
//若你的字符串并不存在拆分的格式,那么拆分后任是原来的字符串,长度为1
System.out.println(Arrays.toString(date1));	
//打印结果[198.168.1.1]
字符串查找
//字符串查找
String str = "hello world";
//contains方法判断str字符串中是否包含字符串"world"
System.out.println(str.contains("world"));
//判断字符串是否以此字符串("hello")开头
System.out.println(str.startsWith("hello"));    //打印true
System.out.println(str.startsWith("hello1"));   //打印false
//判断字符串是否以此字符串("world")结尾
System.out.println(str.endsWith("world"));      //打印true
System.out.println(str.endsWith("world1"));     //打印false
字符串截取
String str = "hello world";
//截取字符串,从索引6开始截取
System.out.println(str.substring(6));       //打印结果 world
//截取索引左闭右开区间的字符串
//[0,5)
System.out.println(str.substring(0,5));     //打印结果 hello

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/924206.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-16
下一篇 2022-05-16

发表评论

登录后才能评论

评论列表(0条)

保存