java基础(三)java中String类的作用及常用方法,StringBuffer与StringBuilder的使用理解与String类的区别

java基础(三)java中String类的作用及常用方法,StringBuffer与StringBuilder的使用理解与String类的区别

先看String类的源码

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];

    /** Cache the hash code for the string */
    private int hash; // Default to 0

    /** use serialVersionUID from JDK 1.0.2 for interoperability */
    private static final long serialVersionUID = -6849794470754667710L;

从上面可以看出几点:
1)String类是final类,也即意味着String类不能被继承,并且它的成员方法都默认为final方法。在Java中,被final修饰的类是不允许被继承的,并且该类中的成员方法都默认为final方法。
2)上面列举出了String类中所有的成员属性,从上面可以看出String类其实是通过char数组来保存字符串的。
字符串(String)的一些方法
字符串(String)的一些方法
翻看Java文档,可以看出String类为我们封装了很多的对字符串操作的方法:

int length()
返回此字符串的长度

char charAt(int index)
根据下标获取字符串的某个字符(可以获取某个特定位置的字符)

String concat(String str)
将指定字符串连接到此字符串的结尾(相当于“+”运算符)

boolean contains(CharSequence s)
判断此char值序列s是否在字符串中,存在返回true(可以判断此字符串是否存在某个子串)

boolean endWith(String suffix)
判断此字符串是否以指定的后缀结束(比如在上传图片时,判断上传文件的文件扩展名是否为.jpg)

boolean startWith(String perfix)
判断此字符串是否以指定的前缀开始

booean equals(Object anObject)
将此字符串与指定的字符串进行比较(这个方法是重写了String的父类Object的方法,用来判断两个字符串的值是否相同)

boolean equalsIgnoreCase(String anotherString)
将此字符串和另一个字符串进行比较,不考虑大小写

String format(String format,Object… args)
对字符串进行格式化吃书输出

int indexOf(int ch)
返回指定字符在此字符串中的第一次出现处的索引,不存在指定字符,返回-1

String intern()
返回字符串对象的规范化表示形式

boolean isEmpty()
当且仅当length()为0时返回true

int lastIndexOf(String str)
返回指定字符串在此字符串中最后一次出现的索引

boolean matches(String regex)
判断此字符串是否匹配给定的正则表达式

String replace(CharSequence target,CharSequence replacement)
替换字符串

String[] split(String regex)
根据给定的正则表达式来拆分此字符串

String substring(int beginIndex,int endIndex)
字符串截取,从beginIndex索引截取到endIndex处

char[] toCharArray()
把此字符串转换成一个新的char数组

String toLowerCase()
把此字符串中的所有字符都转换为小写

String toUpperCase()
把此字符串中的所有字符都转换为大写

String toString()
用字符串的形式来返回此对象本身(它已经是一个字符串)

String valueOf(int i)
返回int参数的字符串形式(也就是所谓的类型转换,相应的还有其他基础数据类型的,比如boolean,double,long,char)
String、StringBuffer和StringBuilder的区别
1.对象的可变与不可变
  String类中使用字符数组来保存数据,因为有“final”修饰符,所以string对象是不可变的。如下:

private final char value[];

StringBuilder与StringBuffer都继承自AbstractStringBuilder类,在AbstractStringBuilder中也是使用字符数组保存数据,这两种对象都是可变的。如下:

char[] value;

2.是否是线程安全
  String中的对象是不可变的,也就可以理解为常量,所以是线程安全。
  AbstractStringBuilder是StringBuilder与StringBuffer的公共父类,定义了一些字符串的基本操作,如expandCapacity、append、insert、indexOf等公共方法。
  StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。看如下源码:

public synchronized StringBuffer reverse() {
2      super.reverse();
3      return this;
4  }
5
6  public int indexOf(String str) {
7      return indexOf(str, 0);        //存在 public synchronized int indexOf(String str, int fromIndex) 方法
8  }

StringBuilder并没有对方法进行加同步锁,所以是非线程安全的。
3.StringBuilder与StringBuffer共同点
  StringBuilder与StringBuffer有公共的抽象父类AbstractStringBuilder。
  抽象类与接口的一个区别是:抽象类中可以定义一些子类的公共方法,子类只需要增加新的功能,不需要重复写已经存在的方法;而接口中只是对方法的申明和常量的定义。
  StringBuilder、StringBuffer的方法都会调用AbstractStringBuilder中的公共方法,如super.append(…)。只是StringBuffer会在方法上加synchronized关键字,进行同步。
如果程序不是多线程的,那么使用StringBuilder效率高于StringBuffer。
创建了几个对象的问题

 String str1 = "abc";
 String str2 = new String("abc");

对于1中的 String str1 = “abc”,首先会检查字符串常量池中是否含有字符串abc,如果有则直接指向,如果没有则在字符串常量池中添加abc字符串并指向它.所以这种方法最多创建一个对象,有可能不创建对象。
对于2中的String str2 = new String(“abc”),首先会在堆内存中申请一块内存存储字符串abc,str2指向其内存块对象。同时还会检查字符串常量池中是否含有abc字符串,若没有则添加abc到字符串常量池中。所以 new String()可能会创建两个对象。
所以如果以上两行代码在同一个程序中,则1中创建了1个对象,2中创建了1个对象。如果将这两行代码的顺序调换一下,则1 String str2 = new String(“abc”)创建了两个对象,而2 String str1 = "abc"没有创建对象。
String的匹配相等问题
使用String类经常需要对两个字符串进行对比,看是否相等。有==和equals两种选择(String重写了equals方法),这两者方法区别大:

比对象的内容是否相等使用equals(),比较两个引用是否指向同一个对象时用==;equals()是看内容是否相等,比较好理解。而==是看是否属于同一个对象。
首先还要明白这个概念:常量池在java用于保存在编译期已确定的,已编译的class文件中的一份数据。主要看编译期字符串能否确定。

String ok="ok";  
String ok1=new String("ok");  
System.out.println(ok==ok1);//fasle 

ok指向字符串常量池,ok1指向new出来的堆内存块,new的字符串在编译期是无法确定的。所以输出false。

String ok="apple1";  
String ok1="apple"+1;  
System.out.println(ok==ok1);//true 

编译期ok和ok1都是确定的,字符串都为apple1,所以ok和ok1都指向字符串常量池里的字符串apple1。指向同一个对象,所以为true

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值