Java之String类与StringBuffer类

2023-05-16

一、String类

1.实例化方式

1)直接赋值法

String str="abc";

String类的设计采用了共享设计模式。在JVM底层实际上会自动维护一个对象池(字符串对象池),如果采用直接赋值法赋值,JVM会先在对象池中查找,如果有,则直接引用;如果没有,则将该实例化对象放到对象池中。

所谓对象池就是一个对象数组。优点:减少内存的开销。

2)构造法

String str=new String("abc");

由此可知,如果使用构造法就会开辟两块内存空间,并且其中一块会变为垃圾空间。而且,当new两个相同字符串时,并不会像直接赋值法那样,而是会再次创建开辟内存空间,因此,它的缺点是:容易制造垃圾,不能实现字符串共享。

先开辟的那个对象为匿名对象,new开辟空间后,匿名对象空间就变为了垃圾空间。

2.字符串的相等比较

"=="在基本数据类型中比较的是数值的大小,但是在引用数据类型中,用于对象比较,比较的是两个对象所保存的内存地址数值,而没有比较对象的内容。

public class TestString {
    public static void main(String[] args) {
        int a=1;
        int b=1;
        System.out.println(a==b);//true

        String str1="abc";//直接赋值法
        String str2=new String("abc");//构造法
        System.out.println(str1==str2);//false
    }
}

要想比较字符串的内容,必须采用String类提供的equals方法。

  public boolean equals(Object anObject)
public class TestString {
    public static void main(String[] args) {
        String str1="abc";//直接赋值法
        String str2=new String("abc");//构造法
        System.out.println(str1==str2);//false
        System.out.println(str1.equals(str2));//true
    }
}

String类中“==”与"equals"的区别?

“==”用于比较对象的堆空间地址的大小;而equals方法用于比较两个字符串的内容是否相等。

3.String的匿名对象

在任何语言的底层,都不会提供有直接的字符串类型。现在所谓的字符串只是高级语言提供给用户开发的支持而已。在Java中,也没有直接提供字符串常量的概念。所有使用“”定义的被人本质上都是String的匿名对象。

匿名对象保存在堆内存中。

建议:在以后的开发过程中,如果要判断用户输入的字符串是否等同于特定字符串,一定要先将特定字符串写在前面。

如:

import java.util.Scanner;

public class TestString {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        String input=sc.next();
        System.out.println(input.equals("hello"));//可能会抛出空指针异常,NUllPointerException异常
        System.out.println("hello".equals(input));
    }
}

如果用户输入为空,就会抛出异常,为避免此异常,我们通常将特定字符串写在前面。推荐第二种写法。

任何的字符串都是String的匿名对象,所以该对象不会为null。

4.构造法的String对象入池

在String类中,提供有intern()使String对象入池。

import java.util.Scanner;

public class TestString {
    public static void main(String[] args) {
        String s1=new String("abc");
        String s2="abc";
        System.out.println(s1.equals(s2));//true
        System.out.println(s1==s2);//false
        String s3=s1.intern();
        System.out.println(s3==s2);//true
        System.out.println(s1.intern()==s2);//true
    }
}

5.字符串常量不可变更

所有语言对字符串的底层实现,都是字符数组。而数组最大的缺陷就是长度固定,因此在定义字符串常量时,它的内容不可改变。

      String str="hello";
      str=str+"world";
      str+="!!!";
      System.out.println(str);

以上字符串的变更属于字符串对象的变更,而非字符串常量的变更,改变的是字符串对象的引用。这个过程中共产生了5个对象,而且都不在对象池中,而是在堆空间中。

String str="hello"+" world"+"!!!";//编译器会将它优化为String str="hello world!!!"

开发原则:

1)字符串定义采用直接赋值法。

2)字符串内容的比较采用String类的equals方法。

3)字符串不应该改变太多,避免产生大量垃圾。

6.与字符串有关的一些方法

6.1 与字符相关的一些方法

public String(char[] value);//将字符数组中的所有内容变为字符串
public String(char[] value,int offset,int count);//将部分字符数组中的内容变为字符串,从下标为offset处开始,取长度为count的字符。
public char charAt(int index);//取得指定索引处得字符,索引从0开始。
public char[] toCharArray();//将字符串变为普通数组返回
import java.util.Scanner;

public class TestString {
    public static void main(String[] args) {
        char[] ch=new char[]{'J','a','v','a',' ','S','E'};
        String str=new String(ch);
        String str2=new String(ch,1,5);
        System.out.println(str);//Java SE
        System.out.println(str2);//ava S
        char c=str.charAt(5);
        System.out.println(c);//S
        String str3="hello";
        char[] chars=str3.toCharArray();
        for(int i=0;i<chars.length;i++){
            System.out.print(chars[i]+" ");//h e l l o
        }
        System.out.println();
    }
}

6.2 与字节有关的方法

字节常用于数据传输以及编码转换的处理中,在String类中提供有字节的支持。

字节并不适合处理中文,只有字符适合处理中文。一个字符等于两个字节。字节只适合处理二进制数据。

public String(byte[] bytes);//将字节数组变为字符串
public String(byte[] bytes,int offset,int length);//将部分字节数组中的内容变为字符串
public byte[] getBytes();//将字符串以字节数组的形式返回
public byte[] getBytes(String charsetName);//编码转换处理
import java.util.Scanner;

public class TestString {
    public static void main(String[] args) {
        String str="helloworld";
        byte[] data=str.getBytes();
        for(int i=0;i<data.length;i++){
            data[i]-=32;
            System.out.print(data[i]+" ");
        }
        System.out.println();
        System.out.println(new String(data));
    }
}

6.3 字符串比较

public boolean equals(Object anObject);//区分大小写的比较
public boolean equalsIgnoreCase(String anotherString);//不区分大小写的比较
public int compareTo(String anotherString);//比较两个字符串的大小关系 相等,返回0;小于,返回内容小于0;大于,返回内容大于0.
import java.util.Scanner;

public class TestString {
    public static void main(String[] args) {
        String str1="hello";
        String str2="HELLO";
        System.out.println(str1.equals(str2));
        System.out.println(str1.equalsIgnoreCase(str2));
        System.out.println(str1.compareTo(str2));
    }
}

6.4 字符串查找

public boolean contains(CharSequence s);//判断一个子字符串是否存在
public int indexOf(String str);//从头开始查找指定字符串的位置,查到了返回位置的开始索引,没有找到返回-1.
public int indexOf(String str,int fromIndex);//从指定位置开始查找子字符串位置,查不到返回-1.
public int lastIndexOf(String str);//由后向前查找子字符串位置
public int lastIndexOf(String str,int fromIndex);//从指定位置由后向前开始查找子字符串位置。
public boolean startsWith(String prefix);//判断是否以指定字符串开头
public boolean startsWith(String prefix,int toffset);//从指定位置开始判断是否以指定字符串开头
public boolean endsWith(String suffix);//判断是否以指定字符串结尾

查找字符串,最好用最方便的是contains(String str)方法。该方法是在JDK1.5以后才有的。

使用indexOf,如果内容重复,则只返回查找的第一个位置。

6.5 字符串替换

public String replaceAll(String regex,String replacement);//替换所有的指定内容
public String replaceFirst(String regex,String replacement);//替换首个指定内容

6.6 字符串拆分

public String[] split(String regex);//将字符串拆分
public String[] split(String regex,int limit);//将字符串部分拆分,该数组长度就是limit极限。
import java.util.Scanner;

public class TestString {
    public static void main(String[] args) {
       String str="Java SE is best";
       String[] strings=str.split(" ");
       for(String s:strings){
           System.out.println(s);
       }
        System.out.println("================================");
       String[] res=str.split(" ",2);
       for(String s:res){
           System.out.println(s);
       }
    }
}

6.7 字符串截取

public String substring(int beginIndex);//从指定索引截取到结尾
public String substring(int beginIndex,int endIndex);//截取部分内容,不包括endIndex处的字符
import java.util.Scanner;

public class TestString {
    public static void main(String[] args) {
       String str="Java SE is best";
       String str1=str.substring(11);
        System.out.println(str1);
        String str2=str.substring(0,7);
        System.out.println(str2);
    }
}

注意:substring(int beginIndex,int endIndex);截取的字符串不包括endIndex处的字符。

6.8 字符串其它操作方法 

public String trim();//去掉字符串中的左右空格,保留中间空格。
public String toUpperCase();//字符串转大写
public String toLowerCase();//字符串转小写
public native String intern();//构造法的字符串入池操作
public String concat(String str);//字符串连接,等同于"+",不入池。
public int length();//取得字符串长度
public boolean isEmpty();//判断是否为空字符串,但不是null,而是长度为0.
import java.util.Scanner;

public class TestString {
    public static void main(String[] args) {
       String str="  Java SE is best   ";
        System.out.println(str);
        System.out.println(str.trim());
        System.out.println(str.toUpperCase());
        System.out.println(str.toLowerCase());
        System.out.println(str.concat("yes"));
        System.out.println(str.length());
    }
}

二、StringBuffer类

字符串常量不能修改,为了方便字符串的修改,提供StringBuffer类。在String类中使用"+"进行字符串连接,但是在StringBuffer类中使用append(str)函数来实现。

1.StringBuffer类的构造方法

a.StringBuffer()//建立一个空的字符缓冲区,初始容量为16个字符。
b.StringBuffer(int length)//指定字符长度为length,建立空的字符缓冲区。
c.StringBuffer(String str)//缓冲区的初始内容为str,并另外提供16个字符的初始容量。

说明:即使两个StringBuffer类的对象,内容相同,但是用equals()函数,比较其内容,结果仍然为false.

2.String类和StringBuffer类的相互转换

String类型转为StringBuffer类:StringBuffer的构造方法或者append()。

StringBuffer类型转为String类型:调用toStirng()。

import java.util.Scanner;

public class TestString {
    public static void main(String[] args) {
        StringBuffer s1=new StringBuffer();
        s1.append("hello world");
        StringBuffer s2=new StringBuffer();
        System.out.println(s2.append("hello world").toString());
        System.out.println(s1);
        System.out.println(s2);
        System.out.println(s1==s2);//false
        System.out.println(s1.equals(s2));//false
        String str="hello";
        System.out.println(str.toString());
    }
}

3.StringBuffer的常用方法

3.1 与String类用法相同的方法

 (1)length()//返回字符串的字符个数。
 (2)toString()//返回缓冲区中的字符串。(两个类函数的实现方法不同,具体见2.3.2)
 (3)charAt(int index)//返回字符串中下标是index的字符。
 (4)getChars(int srcBegin,int secEnd,char[] dst,int dstBegin)//将字符串下标为[srcBegin,srcEnd)的字符串赋值给dst从下标为
                                dstBegin开始的一组字符。
 (5)substring(int beginIndex,int endIndex)//返回原字符串的一个子串[beginIndex,endIndex)

3.2 StringBuffer类独有的方法

1)setCharAt(int index,char ch)//在下标为index的位置上添加字符ch,相当替换该位置上的原有字符。

public class Astring{
	public static void main(String[] args){
		StringBuffer s1=new StringBuffer();
		s1.append("world");
		System.out.println(s1.charAt(3));//l
		s1.setCharAt(3,'h');
		System.out.println(s1);//worhd
	}
}

2)append()//向缓冲区中添加新的字符串。

public class Astring{
	public static void main(String[] args){
		StringBuffer s1=new StringBuffer();
		s1.append("hello");
		System.out.println(s1);//hello
		s1.append(" world");
		System.out.println(s1);//hello world
	}
}

3)insert(int Offset,String str);//在字符串中的offset位置插入字符串str.(不替换)

public class Astring{
	public static void main(String[] args){
		StringBuffer s1=new StringBuffer();
		s1.append("hello");
		System.out.println(s1);//hello
		s1.append(" world");
		System.out.println(s1);//hello world
		s1.insert(5,"!!!");
		System.out.println(s1);//hello!!! world
	}
}

4)reverse()//字符串反转函数。

public class Astring{
	public static void main(String[] args){
		StringBuffer s1=new StringBuffer();
		s1.append("hello");
		System.out.println(s1);//hello
		System.out.println(s1.reverse());//olleh
	}
}

5)delete(int start,int end)//删除指定范围的数据 [start,end)

public class Astring{
	public static void main(String[] args){
		StringBuffer s1=new StringBuffer();
		s1.append("hello");
		System.out.println(s1);//hello
		System.out.println(s1.delete(1,4));//ho
	}
}

4.比较String类与StringBuffer类

相同点:

    (1)String类与StringBuffer类都用来处理字符串。
    (2)部分方法在二者中的用法是相同的。eg:length()、toString()、charAt()、substring().
    (3)在这两个类中,字符的索引都是从0开始的。
    (4)这两个类都是CharSequence的子类。CharSequence接口描述的是一系列字符集。

不同点:

(1)String类是不可变类,因为在底端是用字符数组实现的,而数组长度固定,一旦赋值,就不能在原来的字符串上进行修改可能会浪费空间。StringBuffer类是可变类,能够在原来的数组上进行修改。

如:String类中的substring()、concat()、toLowerCase()、toUpperCase()和trim()等方法都不会改变字符串本身,
而是直接创建并返回一个包含改变后内容的新字符串对象。而StringBuffer的apend()、replaceAll()、insert()、setCharAt()等
方法都会改变字符串缓冲区中的字符串内容。

(2)String类覆盖了Object类的equals()方法,而StringBuffer类没有覆盖该方法。

(3)虽然两个类都覆盖了toString()方法,但各自的实现方式不同。String类的toString()方法返回当前String对象的引用。而StringBuffer类的toString()方法返回一个以当前StringBuffer的缓冲区的所有字符为内容的新的String对象的引用。

(4)String类对象可以用操作符"+"进行连接,而StringBuffer类的对象不能,StringBuffer类的对象可以通过append()方法添加新的字符串。

public class Astring{
	     public static void main(String[] args){
		StringBuffer s1=new StringBuffer();
		s1.append("fjasgnroehoergklfjij");
		StringBuffer s2=new StringBuffer();
		System.out.println(s2.append("fjasgnroehoergklfjij").toString());
		System.out.println(s1);
		System.out.println(s2);
		System.out.println(s1==s2);//false
		System.out.println(s1.equals(s2));//false
		String str="hello";
		System.out.println(str.toString());
	}
}

5.比较String、StringBuffer与StringBuilder

   (1)String的内容不可修改,而StringBuffer和StringBuilder的内容可以修改。
 (2)StringBuffer采用同步处理,属于线程安全操作,而StringBuilder采用异步处理,属于线程不安全操作。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java之String类与StringBuffer类 的相关文章

随机推荐

  • 【C++】C++使用libcurl做HttpClient

    当使用C 43 43 做HTTP客户端时 xff0c 目前通用的做法就是使用libcurl 其官方网站的地址是http curl haxx se xff0c 该网站主要提供了Curl和libcurl Curl是命令行工具 xff0c 用于完
  • STM32F767 采用FIFO模式串口发送接收

    功能 xff1a 将接收到的数据发送出去 UART HandleTypeDef huart1 span class token punctuation span span class token comment 64 brief The a
  • 单片机串口分析起始位停止位奇偶校验位

    串口解析 串口配置 1 波特率 2 停止位 3 数据位 4 奇偶校验位 比特率 xff1a 通讯的频率停止位 xff1a 可以选择1 1 5 2三个选择数据位 xff1a 可以选择5 6 7 8四个选择奇偶校验位 xff1a 可以选择奇校验
  • 在算法研究过程中如何进行算法创新

    FPGA教程目录 MATLAB教程目录 创新一直是一个令人纠结的话题 xff0c 研究生毕业设计多数需要算法的创新 xff0c 而博士生毕业更需要大量的创新才行 另外一方面 xff0c 一些前沿的课题 xff0c 更是对算法的创新有着较高的
  • GPIO口相关配置寄存器

    STM32的每个Px端口都有四种7个寄存器来控制 xff0c 分别是 xff1a 2个32位的端口输入输出模式寄存器CRL CRH 2个32位的数据寄存器IDR ODR 1个32位的置位 复位寄存器BSRR 1个16位的复位寄存器BRR 1
  • STM32串口接收以及发送大全

    串口接收 xff1a 一 一帧数据以 r n结束 协议理解 xff1a 协议嘛 xff0c 就是我们人为创造一条规则 xff0c 按这条规则规规矩矩地来章程执行能够减少错误 xff0c 效率更高 xff0c 都执行一个规则也能大一统 下面我
  • 51单片机串口奇偶校验

    有的单片机串口奇偶校验都是硬件自动完成的 xff0c 但是就我目前用到的很多51核的单片机 xff0c 需要软件做一些简单的处理来完成奇偶校验 可以自己写一个简单的小程序来实现 xff1a 一位一位的判断1的个数 xff0c 这个当然好实现
  • C语言printf()输出格式大全

    这里写自定义目录标题 1 xff0e 转换说明符 a A 浮点数 十六进制数字和p P 记数法 C99 c 字符 d 有符号十进制整数 f 浮点数 包括float和doulbe e E 浮点数指数输出 e E 记数法 g G 浮点数不显无意
  • 2019年 电赛C题 全国大学生电子设计竞赛试题解析与总结

    2019年全国大学生电子设计竞赛试题 电赛C题 分析与总结 线路负载及故障检测装置 本科组 一 题目任务 设计并制作线路负载及故障检测装置 xff0c 示意图如图1所示 检测装置只通过两个连接端子与两根导线连接 导线上A B两点距离各自连接
  • 用moment获取一年内指定周的起始时间和结束时间、用户所选时间和前端传参时间不一致问题

    问题1 xff1a 原代码 xff1a 所选周 selectedWeek handler let selectedWeek 61 parseInt this selectedWeek substring 1 计算所选周的周开始时间和周结束时
  • HTML知识(一)

    1 HTML元素 HTML元素指的是从开始标签 start tag 到结束标签 xff08 end tag xff09 的所有代码 元素内容是开始标签与结束标签之间的内容 某些HTML元素具有空内容 xff0c 空元素在开始标签中进行关闭
  • CSS隐藏元素、BFC、元素居中、布局

    1 css中有哪些方式可以隐藏页面元素 xff1f 区别是什么 xff1f 1 1 display none 元素在页面上将彻底消失 xff0c 元素本身占有的空间会被其他元素占有 xff0c 导致浏览器的重排和重绘 特点 xff1a 元素
  • 响应式设计和CSS提高性能的方法

    一 响应式设计 1 是什么 xff1f 是一种网络页面设计布局 xff0c 页面的设计与开发应当根据用户行为以及设备环境 xff08 系统平台 屏幕尺寸 屏幕定向等 xff09 进行相应的响应和调整 2 常见特点 xff08 1 xff09
  • js事件循环机制

    一 同步任务与异步任务 JavaScript是一门单线程 语言 xff0c 但是单线程并不意味着阻塞 实现单线程非阻塞的方式就是事件循环机制 在JavaScript中 xff0c 所有的事件都可以分为同步任务和异步任务 同步任务 xff1a
  • 简易MIMO-OFDM系统的设计

    0 完整源码获得方式 订阅MATLAB FPGA教程 xff0c 免得获得教程案例以及任意2份完整源码 MIMO OFDM系统的接收信号是多个发射天线发送信号的衰落与加性噪声的线性叠加 xff0c 若采用通常SISO OFDM系统或MIMO
  • 栈的定义和操作

    一 栈的定义 栈是一种操作受限制的线性表 xff0c 将允许进行插入 删除的一端称为栈顶 xff0c 另一端称为栈底 二 栈的分类 栈主要分为静态栈和动态栈 xff0c 静态栈类似于数组 xff0c 而动态栈类似于链表 xff0c 但只能对
  • 用C语言和前序遍历创建一棵二叉树

    一 二叉树的介绍 二叉树的特点是二叉树的每个结点的度都不大于2 xff0c 可以视为每个结点都有左孩子和右孩子 故二叉树结点的数据结构为 typedef int BDataType typedef struct BTNode BDataTy
  • 超市购物程序设计

    一 任务介绍 1 任务描述 去超市购物说人们日常生活的重要事情之一 在超市中有很多日常生活的用法 xff0c 如水果 蔬菜 洗衣机 电冰箱等 人们只能买到超市中的已有商品 xff0c 如果所需要的商品在超市中没有或已经卖完了 xff0c 那
  • 如何在IDEA中配置XML、添加XML文件样板以及设置项目编码方式

    一 如何在IDEA中配置XML 1 首先保证本地电脑上有apache maven包 xff0c 打开IDEA 2 点击File下拉菜单中的Settings xff0c 弹出Settings菜单框 3 在弹出的菜单框中选择Build Exec
  • Java之String类与StringBuffer类

    一 String类 1 实例化方式 1 xff09 直接赋值法 String str 61 34 abc 34 String类的设计采用了共享设计模式 在JVM底层实际上会自动维护一个对象池 xff08 字符串对象池 xff09 xff0c