常用类的笔记

Object类

大家都知道object是所有类的父类,任何类都默认继承Object.
理论上Object类是所有类的父类,即直接或间接地继承java.lang.Object类.
由于所有类都继承在Object类,因此省略了extends Object关键字.
该类中主要由以下方法:

  • toString()
  • getClass()
  • equals
  • clone()
  • finalize
  • 其中toString(),getClass(),equals是其中最重要的方法.

演示:查看Object类源码
在这里插入图片描述
注意:Object类中的getClass(),notify(),notifyAll(),wait()等方法被定义为final类型,因此不能重写.

1.Clone()方法

clone顾名思义就是复制,在java语言中,clone()方法被对象调用,所有会复制对象.所谓的复制对象,首先要分配一个和源对象同样大小的空间,在这个空间创建一个新的对象,那么在java语言中,有几种方法可以创建对象呢?

  • 使用new操作符创建一个对象
  • 使用clone方法复制一个对象
    那么这两种方式有什么相同和不同呢? new操作符的本意是分配内存。程序执行到new操作符时, 首先去看new操作符后面的类型,因为知道了类型,才能知道要分配多大的内存空间。分配完内存之后,再调用构造函数,填充对象的各个域,这一步叫做对象的初始化,构造方法返回后,一个对象创建完毕,可以把他的引用(地址)发布到外部,在外部就可以使用这个引用操纵这个对象。而clone在第一步是和new相似的, 都是分配内存,调用clone方法时,分配的内存和源对象(即调用clone方法的对象)相同,然后再使用原对象中对应的各个域,填充新对象的域, 填充完成之后,clone方法返回,一个新的相同的对象被创建,同样可以把这个新对象的引用发布到外部.
    clone与copy的区别
    假设现在有一个Employee对象,Employee tobby = new Employee(“MTobby”,5000)
    通常我们会有这样的赋值Employee cindyelf=tobby,这个时候只是简单了copy了一下reference,
    cindyelf和tobby都指向内存中同一个object,这样cindyelf或者tobby的一个操作都可能影响到对方。打个比方,如果我们通过cindyelf.raiseSalary()方法改变了salary域的值,那么tobby通过getSalary()方法得到的就是修改之后的salary域的值,显然这不是我们愿意看到的。我们希望得到tobby的一个精确拷贝,同时两者互不影响,这时候, 我们就可以使用Clone来满足我们的需求。Employeecindy=tobby.clone(),这时会生成一个新的Employee对象,并且和tobby具有相同的属性值和方法。
    shallow Clone 与 Deep Clone
    主要是JAVA里除了8种基本类型传参数是值传递,其他的类对象传参数都是引用,我们有时候不希望在方法里将参数改变,这是就需要在类中复写clone方法(实现深复制)。
    Clone是如何完成的呢?Object在对某个对象实施Clone时对其是一无所知的,它仅仅是简单地执行域对域的copy,这就是Shallow Clone。这样,问题就来了咯。
    以Employee为例,它里面有一个域hireDay不是基本数据类型的变量,而是一个reference变量,经过Clone之后就会产生一个新的Date型的reference,
    它和原始对象中对应的域指向同一个Date对象,这样克隆类就和原始类共享了一部分信息,而这样显然是不利的,过程下图所示:
    在这里插入图片描述
    这个时候我们就需要进行deep Clone了,对那些非基本类型的域进行特殊的处理,例如本例中的hireDay。我们可以重新定义Clone方法,对hireDay做特殊处理,如下代码所示:
Class Employee implements Cloneable{
	public Object clone() throws CloneNotSupportedException{
		Employee cloned = (Employee) super.clone();
		clone.hireDay = (Date).haieDau.clone();
		return cloned;
	}
		}

clone方法的保护机制
在Object中Clone()是被声明为protected的,这样做是由一定的道理的,以Employee类为例,通过声明为protected,就可以保证只有Employee类里面才能克隆Employee对象。

clone方法的使用
什么时候使用shallow Clone,什么时候使用deep Clone,这个主要看具体对象的域是什么性质的,基本型别还是reference variable调用Clone()方法的对象所属的类(Class)必须implements Clonable接口,否则在调用Clone方法的时候会抛CloneNotSupportedException

2.toString()方法

public String toString(){
	return getClass.getName+'@'+Integer.toHexString(hashCode());
}

Object 类的 toString 方法返回一个字符串,该字符串由类名(对象是该类的一个实例)、at 标记符“@”和此对象哈希码的无符号十六进制表示组成。
该方法用的比较多,一般子类都有覆盖
我们推荐在学习阶段所有有属性的类都加上toString()方法!

public static void main(String[] args){
	Object o1 = new Object();
	System.out.println(o1.toString);
}

3.getClass()方法

public final native Class<?>getClass();

返回Object的运行使类类型
不可重写,要调用的话,一般和getName()联合,如getClass().getName();

  public static void main(String[] args) {
        Object a = new Object();
        System.out.println(a.getClass().getName());
    }
}

4.finalize()方法

protected void finalize() throws Throwable{}

该方法用于释放资源。因为无法确定该方法什么时候被调用,很少使用。
Java允许在类中定义一个名为finalize()的方法。它的工作原理是:一旦垃圾回收器准备好释放对象占用
的存储空间,将首先调用其finalize()方法。并且在下一次垃圾回收动作发生时,才会真正回收对象占用的内存。关于垃圾回收,有三点需要记住:
1.对象可能不被垃圾回收。只要程序没有濒临存储空间用完的那一刻,对象占用的空间就总得不到释放。
2.垃圾回收并不等于“析构”。
3.垃圾回收只与内存有关。使用垃圾回收的唯一原因是为了回收程序不再使用的内存。
finalize()的用途:
无论对象是如何创建的,垃圾回收器都会负责释放对象占据的所有内存。
这就将对finalize()的需求限制到一种特殊情况,即通过某种创建对象方式以外的方式为对象分配了存储空间。不过这种情况一般发生在使用“本地方法”的情况下,本地方法是一种在Java中调用非Java代码的方式。

5.equals()方法

	public boolean equals(Object obj){
		return (this == obj);
}

Object中的equals方法是直接判断this和obj本身的值是否相等,即用来判断调用equals的对象和形参obj指是否是同一块对象,
所谓同一对象就是指内存中同一块存储单元,如果this和obj指向的hi同一块内存对象,则返回true,如果this和obj指向的不是同一块内存,则返回false。
注意:即便是内容完全相等的两块不同的内存对象,也返回false。
如果是同一块内存,则object中的equals方法返回true,如果是不同的内存,则返回false
如果希望不同内存但相同内容的两个对象equals时返回true,则我们需要重写父类的equal方法
String类已经重写了object中的equals方法(这样就是比较内容是否相等了)
【演示:查看String类源码equals方法】

  public boolean equals(Object anObject) {
       if (this == anObject) {
           return true;
       }
       if (anObject instanceof String) {
           String anotherString = (String)anObject;
           int n = value.length;
           if (n == anotherString.value.length) {
               char v1[] = value;
               char v2[] = anotherString.value;
               int i = 0;
               while (n-- != 0) {
                   if (v1[i] != v2[i])
                       return false;
                   i++;
               }
               return true;
           }
       }
       return false;
   }

6.hashCode()方法

public native int hashCode();

返回该对象的哈希码值。
该方法用于哈希查找,可以减少在查找中使用equals的次数,重写了equals方法一般都要重写
hashCode方法。这个方法在一些具有哈希功能的Collection中用到。
一般必须满足obj1.equals(obj2)==true。可以推出obj1.hashCode()= obj2.hashCode(),但是hashCode相等不一定就满足equals。不过为了提高效率,应该尽量使上面两个条件接近等价。

包装类

1.包装类介绍

虽然 Java 语言是典型的面向对象编程语言,但其中的八种基本数据类型并不支持面向对象编程,基本类型的数据不具备“对象”的特性——不携带属性、没有方法可调用。 沿用它们只是为了迎合人类根深蒂固的习惯,并的确能简单、有效地进行常规数据处理。
这种借助于非面向对象技术的做法有时也会带来不便,比如引用类型数据均继承了 Object 类的特性,要转换为 String 类型(经常有这种需要)时只要简单调用 Object 类中定义的toString()即可,而基本数据类型转换为 String 类型则要麻烦得多。为解决此类问题 ,Java为每种基本数据类型分别设计了对应的类,称之为包装类(Wrapper Classes),也有教材称为外覆类或数据类型类。
在这里插入图片描述每个包装类的对象可以封装一个相应的基本类型的数据,并提供了其它一些有用的方法。包装类对象一经创建,其内容(所封装的基本类型数据值)不可改变。
基本类型和对应的包装类可以相互装换:

  • 由基本类型向对应的包装类转换称为装箱,例如把 int 包装成 Integer 类的对象;
  • 包装类向对应的基本类型转换称为拆箱,例如把 Integer 类的对象重新简化为 int。

2.包装类的应用

【1.实现int和Integer的相互转换】
可以通过Integer类的构造方法将int装箱,通过Integer类的intValue方法将Integer拆箱。

public static void main(String[] args) {
       int m = 50;
       Integer obj = new Integer(50);//手动装箱
        int n = obj.intValue();//手动拆箱
        System.out.println("n="+n);
        Integer obj1 = new Integer(500);
        System.out.println("Obj等价于objs=1?"+obj.equals(obj1));
    }

【2.将字符串转换为整数】
Integer类有一个静态的pasentInt()方法,可以将字符串转化为整数,语法为:

parseInt(String s,int radix);

s为要转换的字符串,radix为进制,可选,默认为十进制。
下面的代码将会告诉你什么样的字符串可以转化为整数:

public static void main(String[] args) {
String[] str = {"123", "123abc", "abc123", "abcxyz"};
for(String str1 : str){
try{
int m = Integer.parseInt(str1, 10);
System.out.println(str1 + " 可以转换为整数 " + m);
}catch(Exception e){
System.out.println(str1 + " 无法转换为整数");
}
}
}
//结果
123 可以转换为整数 123
123abc 无法转换为整数
abc123 无法转换为整数
abcxyz 无法转化为整数

【3.将整数转换为字符串】
nteger 类有一个静态的 toString() 方法,可以将整数转换为字符串。或者直接在整数后面加空字符串即可!

public static void main(String[] args) {
int m = 500;
String s = Integer.toString(m);
String s2 = m+"";
System.out.println("s = " + s);
}

3.自动拆箱和装箱

上面的例子都需要手动实例化一个包装类,称为手动拆箱装箱。Java 1.5(5.0) 之前必须手动拆箱装箱。Java 1.5 之后可以自动拆箱装箱,也就是在进行基本数据类型和对应的包装类转换时,系统将自动进行,这将大大方便程序员的代码书写。

  public static void main(String[] args) {
       int m = 50;
       Integer obj = new Integer(50);//手动装箱
        int n = obj.intValue();//手动拆箱
        System.out.println("n="+n);
        Integer obj1 = new Integer(500);
        System.out.println("Obj等价于objs=1?"+obj.equals(obj1));
    }
    //结果
    // n = 500
    // obj等价于obj1?true

自动装箱与拆箱的功能事实上是编译器来帮您的忙,编译器在编译时期依您所编写的语法,决定是否进行装箱或拆箱动作。例如:

Integer i = 500;
相等于编译器自动为您作为以下的语法编译
Integer i = new Integer(500);

所以自动装箱与拆箱的功能是所谓的“编译器蜜糖”(Compiler Sugar),虽然使用这个功能很方便,但在程序运行阶段您得了解Java的语义。例如下面的程序是可以通过编译的:

Integer i = null;
int j = i;

这样的语法在编译时期是合法的,但是在运行期间会由错误,因为这种写法相当于:

Integer i =null
int j = i.intValue;

null表示i 没有参考至任何的对象实体,它可以合法地指定给对象参考名称。由于实际上i并没有参考至任何的对象,所以也就不可能操作intValue()方法,这样上面的写法在运行时会出现NullPointerException错误。自动拆箱装箱是常用的一个功能,需要重点掌握。
一般地,当需要使用数字的时候,我们通常使用内置数据类型,如:byte、int、long、double 等。然而,在实际开发过程中,我们经常会遇到需要使用对象,而不是内置数据类型的情形。为了解决这个问题,Java 语言为每一个内置数据类型提供了对应的包装类
所有的包装类(Integer、Long、Byte、Double、Float、Short)都是抽象类 Number 的子类。

Math类

java的Math包含了用于执行基本数学运算的属性和方法,如初等函数,对数,平方根和三角函数。
Math的方法都被定义为static形式,通过Math类可以在主函数中直接调用。
【演示:查看Math类的源码】

public final Class Math{
}

【常用值与函数】
Math.PI 记录的圆周率
Math.E 记录e的常量
Math中还有一些类似的常量,都是一些工程数学常用量。
Math.abs 求绝对值
Math.sin 正弦函数 Math.asin 反正弦函数
Math.cos 余弦函数 Math.acos 反余弦函数
Math.tan 正切函数 Math.atan 反正切函数 Math.atan2 商的反正切函数
Math.toDegrees 弧度转化为角度 Math.toRadians 角度转化为弧度
Math.ceil 得到不小于某数的最大整数
Math.floor 得到不大于某数的最大整数
Math.IEEEremainder 求余
Math.max 求两数中最大
Math.min 求两数中最小
Math.sqrt 求开方
Math.pow 求某数的任意次方, 抛出ArithmeticException处理溢出异常
Math.exp 求e的任意次方
Math.log10 以10为底的对数
Math.log 自然对数
Math.rint 求距离某数最近的整数(可能比某数大,也可能比它小)
Math.round 同上,返回int型或者long型(上一个函数返回double型)
Math.random 返回0,1之间的一个随机数

Random类

java中存在着两种Random函数;

1.java.lang.Math.Random;

调用这个Math.Random()函数能够返回带正号的double的值,该值大于等于0.0且小于1.0,即取值范围是[0.0,1.0)的左闭右开区间,返回值是一个伪随机选择的数,在该范围内均匀分布,例子如下:

public static void main(String[] args) {
// 结果是个double类型的值,区间为[0.0,1.0)
System.out.println("Math.random()=" + Math.random());
int num = (int) (Math.random() * 3);
// 注意不要写成(int)Math.random()*3,这个结果为0或1,因为先执行了强制转换
System.out.println("num=" + num);
}
//结果
//Math.random()=0.44938147153848396
//num=1

2.java.util.Random

下面是Random()的两种构造方法;
Random():创建一个新的随机数生成器。
Random(long seed):使用单个 long 种子创建一个新的随机数生成器。
你在创建一个Random对象的时候可以给定任意一个合法的种子数,种子数只是随机算法的起源数字,和生成的随机数的区间没有任何关系。
如下面的java代码:
【演示一】
在没带参数构造函数生成的Random对象的种子缺省是当前系统时间的毫秒数。
rand.nextInt(100)中的100是随机数的上限,产生的随机数为0-100的整数,不包括100。

public static void main(String[] args){
	Random rand = new Random();
	int i = rand.nextInt(100);
	System.out.println(i);
}

【演示二】
对于种子相同的Random对象,生成的随机数序列是一样的

public static void main(String[] args) {
Random ran1 = new Random(25);
System.out.println("使用种子为25的Random对象生成[0,100)内随机整数序列: ");
for (int i = 0; i < 10; i++) {
System.out.print(ran1.nextInt(100) + " ");
}
System.out.println();
}

【例子】
1.生成[0,1.0)区间的小数:double d1 = r.nextDouble();
2.生成[0,5.0)区间的小数:double d2 = r.nextDouble()*5;
3…生成[1,2.5)区间的小数:double d3 = r.nextDouble() * 1.5 + 1;
4. 生成[0,10)区间的整数:int n2 = r.nextInt(10);

日期时间类

1.Date类

java.util 包提供了 Date 类来封装当前的日期和时间。Date 类提供两个构造函数来实例化 Date 对象。第一个构造函数使用当前日期和时间来初始化对象.

Date()

第二个构造函数接收一个参数,该参数是从1970年1月1日起的毫秒数。

Date(long millosec)

Date对象创建以后,可以调用下面的方法。
在这里插入图片描述【演示:获取当前日期时间】
java中获取当前日期和时间很简单,使用 Date 对象的 toString() 方法来打印当前日期和时间

public static void main(String[] args) {
        Date date =new Date();
        System.out.println(date.toString());
    }

【演示:日期比较】

  • 使用getTime()方法获取两个日期(自1970年1月1日经历的毫秒数值),然后比较这两个值。
public static void main(String[] args){
	//初始化Date对象
	Date date = new Date();
	long time1= date.getTime();
	long time2=date.getTime();
	System.out.println(time1==time2)
}
  • 使用方法before(),after(),equals().例如,一个月的12号比18号早,则new Date(99,2,12).before(new Date(99,2,18))返回true。
public static void main(String[] args){
	boolean before = new Date(97,01,05).before(new Date(99,11,16));
	System.out.println(before);
}

2.SimpleDateFormat

【演示:使用SimpleDateFormat格式化日期】
SimpleDateFormat 是一个以语言环境敏感的方式来格式化和分析日期的类。SimpleDateFormat 允许你选择任何用户自定义日期时间格式来运行。例如:
在这里插入图片描述
其中 yyyy 是完整的公元年,MM 是月份,dd 是日期,HH:mm:ss 是时、分、秒。
注意:有的格式大写,有的格式小写,例如 MM 是月份,mm 是分;HH 是 24 小时制,而 hh 是 12 小时制。

String类

1.String概述

在API中是这样描述:
String 类代表字符串。Java 程序中的所有字符串字面值(如 “abc” )都作为此类的实例实现。 字符串是常量;它们的值在创建之后不能更改。字符串缓冲区支持可变的字符串。因为 String 对象是不可变的,所以可以共享。

【演示:查看String源码】

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence{
    }

【String的成员变量】

private final char value[];
private int hash; // Default to 0
private static final long serialVersionUID = -6849794470754667710L;
private static final ObjectStreamField[] serialPersistentFields =
        new ObjectStreamField[0];

从源码看出String底层使用一个字符数组来维护的。成员变量可以知道String类的值是final类型的,不能被改变的,所以只要一个值改变就会生成一个新的String类型对象,存储String数据也不一定从数组的第0个元素开始的,而是从offset所指的元素开始。
【String的构造方法】

String()
//初始化一个新创建的 String 对象,使其表示一个空字符序列。
String(byte[] bytes)
//通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String。
String(byte[] bytes, Charset charset)
//通过使用指定的 charset 解码指定的 byte 数组,构造一个新的 String。
String(byte[] bytes, int offset, int length)
//通过使用平台的默认字符集解码指定的 byte 子数组,构造一个新的 String。
String(byte[] bytes, int offset, int length, Charset charset)
//通过使用指定的 charset 解码指定的 byte 子数组,构造一个新的 String。
String(byte[] bytes, int offset, int length, String charsetName)
//通过使用指定的字符集解码指定的 byte 子数组,构造一个新的 String。
String(byte[] bytes, String charsetName)
//通过使用指定的 charset 解码指定的 byte 数组,构造一个新的 String。
String(char[] value)
//分配一个新的 String,使其表示字符数组参数中当前包含的字符序列。
String(char[] value, int offset, int count)
//分配一个新的 String,它包含取自字符数组参数一个子数组的字符。
String(int[] codePoints, int offset, int count)
//分配一个新的 String,它包含 Unicode 代码点数组参数一个子数组的字符。
String(String original)
//初始化一个新创建的 String 对象,使其表示一个与参数相同的字符序列;换句话说,新创建
的字符串是该参数字符串的副本。
String(StringBuffer buffer)
//分配一个新的字符串,它包含字符串缓冲区参数中当前包含的字符序列。
String(StringBuilder builder)
//分配一个新的字符串,它包含字符串生成器参数中当前包含的字符序列。

2.创建字符对象方式

直接赋值方式创建对象是在方法区的常量池

String str = "hello";//直接赋值的方式

通过构造方法创建字符串对象是在堆内存

String str=new String("hello");//实例化的方式

【两种实例化方式的比较】
1.编写代码比较

public static void main(String[] args) {
String str1 = "Lance";
String str2 = new String("Lance");
String str3 = str2; //引用传递,str3直接指向st2的堆内存地址
String str4 = "Lance";
/**
* ==:
* 基本数据类型:比较的是基本数据类型的值是否相同
* 引用数据类型:比较的是引用数据类型的地址值是否相同
* 所以在这里的话:String类对象==比较,比较的是地址,而不是内容
*/
System.out.println(str1==str2);//false
System.out.println(str1==str3);//false
System.out.println(str3==str2);//true
System.out.println(str1==str4);//true
}

在这里插入图片描述
可能这里还是不够明显,构造方法实例化方式的内存图:String str = new String(“Hello”);
在这里插入图片描述
【字符串常量】
在字符串中,如果采用直接赋值的方式(String str=“Lance”)进行对象的实例化,则会将匿名对象
“Lance”放入对象池,每当下一次对不同的对象进行直接赋值的时候会直接利用池中原有的匿名对象,我们可以用对象手工入池。

在这里插入图片描述【两种实例化方式的区别】

  1. 直接赋值(String str = “hello”):只开辟一块堆内存空间,并且会自动入池,不会产生垃圾。
  2. 构造方法(String str= new String(“hello”);):会开辟两块堆内存空间,其中一块堆内存会变成垃圾
    被系统回收,而且不能够自动入池,需要通过public String intern();方法进行手工入池。
  3. 在开发的过程中不会采用构造方法进行字符串的实例化。
    【避免空指向】
    首先了解: == 和public boolean equals()比较字符串的区别==在对字符串比较的时候,对比的是内存地址,而equals比较的是字符串内容,在开发的过程中,
    equals()通过接受参数,可以避免空指向。
String str = null;
if(str.equals("hello")){//空指针异常
}
if("hello".equals(str)){//此时equals会处理null值,可以避免空指针异常
}

【String类对象一旦声明则不可以改变;而改变的只是地址,原来的字符串还是存在的,并且产生垃圾】
在这里插入图片描述

3.String常用的方法

在这里插入图片描述

1.String的判断

【常用办法】

boolean equals(Object obj);比较字符串的内容是否相同
boolean equalsIgnoreCase(String str);比较字符串的内容是否相同,忽略大小写
boolean startsWith(String str); 判断字符串对象是否以指定的str开头
boolean endWith(String str);判断字符串对象是否以指定的str结尾

【演示】

public static void main(String[] args){
	//创建字符串对象
	String s1 = "hello";
	String s2 = "hello";
	String s3 = "Hello";
	//boolean equals(Object obj):比较字符串的内容是否相同
	System.out.println(s1.equals(s2));//true
	System.out.println(s1.equals(s3));//false
	System.out.println("------------");
	//boolean equalsIgnoreCase(String str);比较字符串的内容是否相同,忽悠大小写
	System.out.println(s1.equalsIgnoreCase(s2));//true
	System.out.println(s1.equalsIgnoreCase(s3));//true
	System.out.println("-------------");
	//boolean startsWith(String srt);比较字符串的内容是否相同,忽略大小写
	System.out.println(s1.startswith("he"));//true
	System.out.println(s1.startsWith("ll"));//false
}

2.String的截取

【常用方法】

int length();获取字符串的长度,其实也就是字符个数
char charAt(int index);获取指定索引处的字符
int indexof(String str);获取str在字符串对象中第一次出现的索引
String subString(int start);从start开始截取字符串
String subString(int start,int end);从start开始,到end结束截取字符串。包括start.

【演示】

 public static void main(String[] args) {
        //创建字符串对象
        String s = "helloword";
        //int length();获取字符串的长度,其实也就是字符个数
        System.out.println(s.length());
        System.out.println("-----------");
        //char CharAt(int index);获取指定索引处的字符
        System.out.println(s.charAt(0));//h
        System.out.println(s.charAt(1));//e
        System.out.println("----------");
        //int indexof(String str);获取str在字符串对象中第一次出现的索引
        System.out.println(s.indexOf("l"));//2
        System.out.println(s.indexOf("ow0"));//4
        System.out.println(s.indexOf("ak"));//-1
        System.out.println("---------------");
        //String subString(int start);从start开始截取字符串
        System.out.println(s.substring(0));//helloword
        System.out.println(s.substring(5));//world
        System.out.println("---------");
        //String subString(int start,int end):从start开始,到end结束截取字符
        System.out.println(s.substring((0,s.length()));//helloWorld
        System.out.println(s.substring(3,8));//lowor
    }

3.String的转换

【常用方法】

char[] toCharArray();把字符串转换成字符数组
String toLowerCase();字符串转换为小写字符串
String toUpperCase();把字符串转换成大写字符串

【演示】

public static void main(String args[]){
	//创造字符串对象
	String s ="abcde";
	//char[] toCharArray();把字符串转换为字符数组
	char[] chs = s.toCharArray();
	for(int x = 0 ; x < chs.length;x++){
		System.out.println(chs[x]);
}
	System.out.println("------------");
}
	//String toLowerCase();把字符串转换成小写字符串
	System.out.println("helloword".toUpperCase());

4.其他方法

【常用方法】
去除字符两端空格:String trim()
按照指定字符串分割字符串:String[] spilt(String str)
【演示】

public static void main(String args[]) {
// 创建字符串对象
String s1 = "helloworld";
String s2 = " helloworld ";
String s3 = " hello world ";
System.out.println("---" + s1 + "---");
System.out.println("---" + s1.trim() + "---");
System.out.println("---" + s2 + "---");
System.out.println("---" + s2.trim() + "---");
System.out.println("---" + s3 + "---");
System.out.println("---" + s3.trim() + "---");
System.out.println("-------------------");
// String[] split(String str)
// 创建字符串对象
String s4 = "aa,bb,cc";
String[] strArray = s4.split(",");
for (int x = 0; x < strArray.length; x++) {
System.out.println(strArray[x]);}
}

4.String的不可变性

当我们去阅读源代码的时候,会发现有这样的一句话:

Strings are constant; their values cannot be changed after they are created.

意思就是说:String是个常量,从一出生就注定不可变。
我想大家应该就知道为什么String不可变了,String类被final修饰,官方注释说明创建后不能被改变,但是为什么String要使用final修饰呢?
【了解一个经典面试题】

public static void main(String[] args) {
	String a = "abc";
	String b = "abc";
	String c = new String("abc");
	System.out.println(a==b); //true
	System.out.println(a.equals(b)); //true
	System.out.println(a==c); //false
	System.out.println(a.equals(c)); //true
}

在这里插入图片描述【分析】
因为String太过常用,JAVA类库的设计者在实现时做了个小小的变化,即采用了享元模式,每当生成一个新内容的字符串时,他们都被添加到一个共享池中,当第二次再次生成同样内容的字符串实例时,就共享此对象,而不是创建一个新对象,但是这样的做法仅仅适合于通过=符号进行的初始化。需要说明一点的是,在object中,equals()是用来比较内存地址的,但是String重写了equals()方法,用来比较内容的,即使是不同地址,只要内容一致,也会返回true,这也就是为什么a.equals©返回true的原因了。

【String不可变的好处】

  • 可以实现多个变量引用堆内存中的同一个字符串实例,避免创建的开销。
  • 我们的程序中大量使用了String字符串,有可能是出于安全性考虑。
  • 大家都知道HashMap中key为String类型,如果可变将变的多么可怕。
  • 当我们在传参的时候,使用不可变类不需要去考虑谁可能会修改其内部的值,如果使用可变类的话,可能需要每次记得重新拷贝出里面的值,性能会有一定的损失。

5.字符串常量池

【字符串常量池概述】
1.常量池表
Class文件中存储所有常量(包括字符串)的table。这是Class文件中的内容,还不是运行时的内容,不要理解它是个池子,其实就是Class文件中的字节码指令。
2.运行时常量池
JVM内存中方法区的一部分,这是运行时的内容。这部分内容(绝大部分)是随着JVM运行时候,从常量池转化而来,每个Class对应一个运行时常量池。上一句中说绝大部分是因为:除了 Class中常量池内容,还可能包括动态生成并加入这里的内容。
3.字符串常量池
这部分也在方法区中,但与Runtime Constant Pool不是一个概念,String Pool是JVM实例全局共享的,全局只有一个。JVM规范要求进入这里的String实例叫“被驻留的interned string”,各个JVM可以有不同的实现,HotSpot是设置了一个哈希表StringTable来引用堆中的字符串实例,被引用就是被驻留。
【亨元模式】
其实字符串常量池这个问题涉及到一个设计模式,叫“享元模式”,顾名思义 - - - > 共享元素模式
也就是说:一个系统中如果有多处用到了相同的一个元素,那么我们应该只存储一份此元素,而让所有地方都引用这一个元素 Java中String部分就是根据享元模式设计的,而那个存储元素的地方就叫做“字符串常量池 - String Pool”
【详细分析】

int x = 10;
String y = "hello";

1.首先,10和hello会在hello会在经过javac(或者其他编译器)编译过后变成Class文件中Constant_pool table的内容
2.当我们的程序运行时,也就是说JVM运行时,每个Class Constant_pool table中的内容会被加载到JVM内存中的方法区中各自Class的Runtime Constant pool.
3.一个没有被String pool包含的RuntimeConstant pool中的字符串,串(这里是"hello")会被加入到
String Pool中(HosSpot使用hashtable引用方式),步骤如下:

  1. 在Java Heap(堆)中根据"hello"字面量create一个字符串对象
  2. 将字面量"hello"与字符串对象的引用在hashtable中关联起来键 - 值形式是:“hello” = 对象的引用地址。另外来说,当一个新的字符串出现在Runtime Constant Pool中时怎么判断需不需要在Java Heap中创建新对象呢?策略是这样:会先去根据equals来比较Runtime Constant Pool中的这个字符串是否和String Pool中某一个是相等的(也就是找是否已经存在),如果有那么就不创建,直接使用其引用;反之,就如同上面的第三步。
    如此,就实现了享元模式,提高的内存利用效率

StringBuilder

1.概述

【演示:查看源码及API文档】

public final class StringBuilder extends AbstractStringBuilder
implements java.io.Serializable, CharSequence{
}

StringBuilder 是一个可变的字符序列。它继承于AbstractStringBuilder,实现了CharSequence接口。StringBuffer 也是继承于AbstractStringBuilder的子类;但是,StringBuilder和StringBuffer不同,前者是非线程安全的,后者是线程安全的。
StringBuilder 和 CharSequence之间的关系图如下:
在这里插入图片描述

public final class StringBuffer
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
{

    /**
     * A cache of the last value returned by toString. Cleared
     * whenever the StringBuffer is modified.
     */
    private transient char[] toStringCache;

    /** use serialVersionUID from JDK 1.0.2 for interoperability */
    static final long serialVersionUID = 3388685877147921107L;

    /**
     * Constructs a string buffer with no characters in it and an
     * initial capacity of 16 characters.
     */
    public StringBuffer() {
        super(16);
    }

    /**
     * Constructs a string buffer with no characters in it and
     * the specified initial capacity.
     *
     * @param      capacity  the initial capacity.
     * @exception  NegativeArraySizeException  if the {@code capacity}
     *               argument is less than {@code 0}.
     */
    public StringBuffer(int capacity) {
        super(capacity);
    }

    /**
     * Constructs a string buffer initialized to the contents of the
     * specified string. The initial capacity of the string buffer is
     * {@code 16} plus the length of the string argument.
     *
     * @param   str   the initial contents of the buffer.
     */
    public StringBuffer(String str) {
        super(str.length() + 16);
        append(str);
    }

    /**
     * Constructs a string buffer that contains the same characters
     * as the specified {@code CharSequence}. The initial capacity of
     * the string buffer is {@code 16} plus the length of the
     * {@code CharSequence} argument.
     * <p>
     * If the length of the specified {@code CharSequence} is
     * less than or equal to zero, then an empty buffer of capacity
     * {@code 16} is returned.
     *
     * @param      seq   the sequence to copy.
     * @since 1.5
     */
    public StringBuffer(CharSequence seq) {
        this(seq.length() + 16);
        append(seq);
    }

    @Override
    public synchronized int length() {
        return count;
    }

    @Override
    public synchronized int capacity() {
        return value.length;
    }


    @Override
    public synchronized void ensureCapacity(int minimumCapacity) {
        super.ensureCapacity(minimumCapacity);
    }

    /**
     * @since      1.5
     */
    @Override
    public synchronized void trimToSize() {
        super.trimToSize();
    }

    /**
     * @throws IndexOutOfBoundsException {@inheritDoc}
     * @see        #length()
     */
    @Override
    public synchronized void setLength(int newLength) {
        toStringCache = null;
        super.setLength(newLength);
    }

    /**
     * @throws IndexOutOfBoundsException {@inheritDoc}
     * @see        #length()
     */
    @Override
    public synchronized char charAt(int index) {
        if ((index < 0) || (index >= count))
            throw new StringIndexOutOfBoundsException(index);
        return value[index];
    }

    /**
     * @since      1.5
     */
    @Override
    public synchronized int codePointAt(int index) {
        return super.codePointAt(index);
    }

    /**
     * @since     1.5
     */
    @Override
    public synchronized int codePointBefore(int index) {
        return super.codePointBefore(index);
    }

    /**
     * @since     1.5
     */
    @Override
    public synchronized int codePointCount(int beginIndex, int endIndex) {
        return super.codePointCount(beginIndex, endIndex);
    }

    /**
     * @since     1.5
     */
    @Override
    public synchronized int offsetByCodePoints(int index, int codePointOffset) {
        return super.offsetByCodePoints(index, codePointOffset);
    }

    /**
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */
    @Override
    public synchronized void getChars(int srcBegin, int srcEnd, char[] dst,
                                      int dstBegin)
    {
        super.getChars(srcBegin, srcEnd, dst, dstBegin);
    }

    /**
     * @throws IndexOutOfBoundsException {@inheritDoc}
     * @see        #length()
     */
    @Override
    public synchronized void setCharAt(int index, char ch) {
        if ((index < 0) || (index >= count))
            throw new StringIndexOutOfBoundsException(index);
        toStringCache = null;
        value[index] = ch;
    }

    @Override
    public synchronized StringBuffer append(Object obj) {
        toStringCache = null;
        super.append(String.valueOf(obj));
        return this;
    }

    @Override
    public synchronized StringBuffer append(String str) {
        toStringCache = null;
        super.append(str);
        return this;
    }

    /**
     * Appends the specified {@code StringBuffer} to this sequence.
     * <p>
     * The characters of the {@code StringBuffer} argument are appended,
     * in order, to the contents of this {@code StringBuffer}, increasing the
     * length of this {@code StringBuffer} by the length of the argument.
     * If {@code sb} is {@code null}, then the four characters
     * {@code "null"} are appended to this {@code StringBuffer}.
     * <p>
     * Let <i>n</i> be the length of the old character sequence, the one
     * contained in the {@code StringBuffer} just prior to execution of the
     * {@code append} method. Then the character at index <i>k</i> in
     * the new character sequence is equal to the character at index <i>k</i>
     * in the old character sequence, if <i>k</i> is less than <i>n</i>;
     * otherwise, it is equal to the character at index <i>k-n</i> in the
     * argument {@code sb}.
     * <p>
     * This method synchronizes on {@code this}, the destination
     * object, but does not synchronize on the source ({@code sb}).
     *
     * @param   sb   the {@code StringBuffer} to append.
     * @return  a reference to this object.
     * @since 1.4
     */
    public synchronized StringBuffer append(StringBuffer sb) {
        toStringCache = null;
        super.append(sb);
        return this;
    }

    /**
     * @since 1.8
     */
    @Override
    synchronized StringBuffer append(AbstractStringBuilder asb) {
        toStringCache = null;
        super.append(asb);
        return this;
    }

    /**
     * Appends the specified {@code CharSequence} to this
     * sequence.
     * <p>
     * The characters of the {@code CharSequence} argument are appended,
     * in order, increasing the length of this sequence by the length of the
     * argument.
     *
     * <p>The result of this method is exactly the same as if it were an
     * invocation of this.append(s, 0, s.length());
     *
     * <p>This method synchronizes on {@code this}, the destination
     * object, but does not synchronize on the source ({@code s}).
     *
     * <p>If {@code s} is {@code null}, then the four characters
     * {@code "null"} are appended.
     *
     * @param   s the {@code CharSequence} to append.
     * @return  a reference to this object.
     * @since 1.5
     */
    @Override
    public synchronized StringBuffer append(CharSequence s) {
        toStringCache = null;
        super.append(s);
        return this;
    }

    /**
     * @throws IndexOutOfBoundsException {@inheritDoc}
     * @since      1.5
     */
    @Override
    public synchronized StringBuffer append(CharSequence s, int start, int end)
    {
        toStringCache = null;
        super.append(s, start, end);
        return this;
    }

    @Override
    public synchronized StringBuffer append(char[] str) {
        toStringCache = null;
        super.append(str);
        return this;
    }

    /**
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */
    @Override
    public synchronized StringBuffer append(char[] str, int offset, int len) {
        toStringCache = null;
        super.append(str, offset, len);
        return this;
    }

    @Override
    public synchronized StringBuffer append(boolean b) {
        toStringCache = null;
        super.append(b);
        return this;
    }

    @Override
    public synchronized StringBuffer append(char c) {
        toStringCache = null;
        super.append(c);
        return this;
    }

    @Override
    public synchronized StringBuffer append(int i) {
        toStringCache = null;
        super.append(i);
        return this;
    }

    /**
     * @since 1.5
     */
    @Override
    public synchronized StringBuffer appendCodePoint(int codePoint) {
        toStringCache = null;
        super.appendCodePoint(codePoint);
        return this;
    }

    @Override
    public synchronized StringBuffer append(long lng) {
        toStringCache = null;
        super.append(lng);
        return this;
    }

    @Override
    public synchronized StringBuffer append(float f) {
        toStringCache = null;
        super.append(f);
        return this;
    }

    @Override
    public synchronized StringBuffer append(double d) {
        toStringCache = null;
        super.append(d);
        return this;
    }

    /**
     * @throws StringIndexOutOfBoundsException {@inheritDoc}
     * @since      1.2
     */
    @Override
    public synchronized StringBuffer delete(int start, int end) {
        toStringCache = null;
        super.delete(start, end);
        return this;
    }

    /**
     * @throws StringIndexOutOfBoundsException {@inheritDoc}
     * @since      1.2
     */
    @Override
    public synchronized StringBuffer deleteCharAt(int index) {
        toStringCache = null;
        super.deleteCharAt(index);
        return this;
    }

    /**
     * @throws StringIndexOutOfBoundsException {@inheritDoc}
     * @since      1.2
     */
    @Override
    public synchronized StringBuffer replace(int start, int end, String str) {
        toStringCache = null;
        super.replace(start, end, str);
        return this;
    }

    /**
     * @throws StringIndexOutOfBoundsException {@inheritDoc}
     * @since      1.2
     */
    @Override
    public synchronized String substring(int start) {
        return substring(start, count);
    }

    /**
     * @throws IndexOutOfBoundsException {@inheritDoc}
     * @since      1.4
     */
    @Override
    public synchronized CharSequence subSequence(int start, int end) {
        return super.substring(start, end);
    }

    /**
     * @throws StringIndexOutOfBoundsException {@inheritDoc}
     * @since      1.2
     */
    @Override
    public synchronized String substring(int start, int end) {
        return super.substring(start, end);
    }

    /**
     * @throws StringIndexOutOfBoundsException {@inheritDoc}
     * @since      1.2
     */
    @Override
    public synchronized StringBuffer insert(int index, char[] str, int offset,
                                            int len)
    {
        toStringCache = null;
        super.insert(index, str, offset, len);
        return this;
    }

    /**
     * @throws StringIndexOutOfBoundsException {@inheritDoc}
     */
    @Override
    public synchronized StringBuffer insert(int offset, Object obj) {
        toStringCache = null;
        super.insert(offset, String.valueOf(obj));
        return this;
    }

    /**
     * @throws StringIndexOutOfBoundsException {@inheritDoc}
     */
    @Override
    public synchronized StringBuffer insert(int offset, String str) {
        toStringCache = null;
        super.insert(offset, str);
        return this;
    }

    /**
     * @throws StringIndexOutOfBoundsException {@inheritDoc}
     */
    @Override
    public synchronized StringBuffer insert(int offset, char[] str) {
        toStringCache = null;
        super.insert(offset, str);
        return this;
    }

    /**
     * @throws IndexOutOfBoundsException {@inheritDoc}
     * @since      1.5
     */
    @Override
    public StringBuffer insert(int dstOffset, CharSequence s) {
        // Note, synchronization achieved via invocations of other StringBuffer methods
        // after narrowing of s to specific type
        // Ditto for toStringCache clearing
        super.insert(dstOffset, s);
        return this;
    }

    /**
     * @throws IndexOutOfBoundsException {@inheritDoc}
     * @since      1.5
     */
    @Override
    public synchronized StringBuffer insert(int dstOffset, CharSequence s,
            int start, int end)
    {
        toStringCache = null;
        super.insert(dstOffset, s, start, end);
        return this;
    }

    /**
     * @throws StringIndexOutOfBoundsException {@inheritDoc}
     */
    @Override
    public  StringBuffer insert(int offset, boolean b) {
        // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
        // after conversion of b to String by super class method
        // Ditto for toStringCache clearing
        super.insert(offset, b);
        return this;
    }

    /**
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */
    @Override
    public synchronized StringBuffer insert(int offset, char c) {
        toStringCache = null;
        super.insert(offset, c);
        return this;
    }

    /**
     * @throws StringIndexOutOfBoundsException {@inheritDoc}
     */
    @Override
    public StringBuffer insert(int offset, int i) {
        // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
        // after conversion of i to String by super class method
        // Ditto for toStringCache clearing
        super.insert(offset, i);
        return this;
    }

    /**
     * @throws StringIndexOutOfBoundsException {@inheritDoc}
     */
    @Override
    public StringBuffer insert(int offset, long l) {
        // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
        // after conversion of l to String by super class method
        // Ditto for toStringCache clearing
        super.insert(offset, l);
        return this;
    }

    /**
     * @throws StringIndexOutOfBoundsException {@inheritDoc}
     */
    @Override
    public StringBuffer insert(int offset, float f) {
        // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
        // after conversion of f to String by super class method
        // Ditto for toStringCache clearing
        super.insert(offset, f);
        return this;
    }

    /**
     * @throws StringIndexOutOfBoundsException {@inheritDoc}
     */
    @Override
    public StringBuffer insert(int offset, double d) {
        // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
        // after conversion of d to String by super class method
        // Ditto for toStringCache clearing
        super.insert(offset, d);
        return this;
    }

    /**
     * @since      1.4
     */
    @Override
    public int indexOf(String str) {
        // Note, synchronization achieved via invocations of other StringBuffer methods
        return super.indexOf(str);
    }

    /**
     * @since      1.4
     */
    @Override
    public synchronized int indexOf(String str, int fromIndex) {
        return super.indexOf(str, fromIndex);
    }

    /**
     * @since      1.4
     */
    @Override
    public int lastIndexOf(String str) {
        // Note, synchronization achieved via invocations of other StringBuffer methods
        return lastIndexOf(str, count);
    }

    /**
     * @since      1.4
     */
    @Override
    public synchronized int lastIndexOf(String str, int fromIndex) {
        return super.lastIndexOf(str, fromIndex);
    }

    /**
     * @since   JDK1.0.2
     */
    @Override
    public synchronized StringBuffer reverse() {
        toStringCache = null;
        super.reverse();
        return this;
    }

    @Override
    public synchronized String toString() {
        if (toStringCache == null) {
            toStringCache = Arrays.copyOfRange(value, 0, count);
        }
        return new String(toStringCache, true);
    }

    /**
     * Serializable fields for StringBuffer.
     *
     * @serialField value  char[]
     *              The backing character array of this StringBuffer.
     * @serialField count int
     *              The number of characters in this StringBuffer.
     * @serialField shared  boolean
     *              A flag indicating whether the backing array is shared.
     *              The value is ignored upon deserialization.
     */
    private static final java.io.ObjectStreamField[] serialPersistentFields =
    {
        new java.io.ObjectStreamField("value", char[].class),
        new java.io.ObjectStreamField("count", Integer.TYPE),
        new java.io.ObjectStreamField("shared", Boolean.TYPE),
    };

    /**
     * readObject is called to restore the state of the StringBuffer from
     * a stream.
     */
    private synchronized void writeObject(java.io.ObjectOutputStream s)
        throws java.io.IOException {
        java.io.ObjectOutputStream.PutField fields = s.putFields();
        fields.put("value", value);
        fields.put("count", count);
        fields.put("shared", false);
        s.writeFields();
    }

    /**
     * readObject is called to restore the state of the StringBuffer from
     * a stream.
     */
    private void readObject(java.io.ObjectInputStream s)
        throws java.io.IOException, ClassNotFoundException {
        java.io.ObjectInputStream.GetField fields = s.readFields();
        value = (char[])fields.get("value", null);
        count = fields.get("count", 0);
    }
}

2.常用方法

1.insert

    public static void main(String[] args) {
        System.out.println("---------- testInsertAPIs -----------");
        StringBuilder sbuilder = new StringBuilder();
// 在位置0处插入字符数组
        sbuilder.insert(0, new char[]{'a', 'b', 'c', 'd', 'e'});
// 在位置0处插入字符数组。0表示字符数组起始位置,3表示长度
        sbuilder.insert(0, new char[]{'A', 'B', 'C', 'D', 'E'}, 0, 3);
// 在位置0处插入float
        sbuilder.insert(0, 1.414f);
// 在位置0处插入double
        sbuilder.insert(0, 3.14159d);
// 在位置0处插入boolean
        sbuilder.insert(0, true);
// 在位置0处插入char
        sbuilder.insert(0, '\n');
// 在位置0处插入int
        sbuilder.insert(0, 100);
// 在位置0处插入long
        sbuilder.insert(0, 12345L);
// 在位置0处插入StringBuilder对象
        sbuilder.insert(0, new StringBuilder("StringBuilder"));
// 在位置0处插入StringBuilder对象。6表示被在位置0处插入对象的起始位置(包括),13是
        //结束位置(不包括)
        sbuilder.insert(0, new StringBuilder("STRINGBUILDER"), 6, 13);
// 在位置0处插入StringBuffer对象。
        sbuilder.insert(0, new StringBuffer("StringBuffer"));
// 在位置0处插入StringBuffer对象。6表示被在位置0处插入对象的起始位置(包括),12是结
      //  束位置(不包括)
        sbuilder.insert(0, new StringBuffer("STRINGBUFFER"), 6, 12);
// 在位置0处插入String对象。
        sbuilder.insert(0, "String");
        // 在位置0处插入String对象。1表示被在位置0处插入对象的起始位置(包括),6是结束位置(不包括)
        sbuilder.insert(0,"0123456789",1,6);
        sbuilder.insert(0,'\n');
        //在位置0处插入Object对象,此处以HashMap为例
        HashMap map = new HashMap();
        map.put("1","one");
        map.put("2","two");
        map.put("3","three");
        sbuilder.insert(0,map);
        System.out.println(sbuilder);
          }

2. append

private static void testAppendAPIs() {
System.out.println("------------------- testAppendAPIs -----------------
--");
StringBuilder sbuilder = new StringBuilder();
// 追加字符数组
sbuilder.append(new char[]{'a','b','c','d','e'});
// 追加字符数组。0表示字符数组起始位置,3表示长度
sbuilder.append(new char[]{'A','B','C','D','E'}, 0, 3);
// 追加float
sbuilder.append(1.414f);
// 追加double
sbuilder.append(3.14159d);
// 追加boolean
sbuilder.append(true);
// 追加char
sbuilder.append('\n');
// 追加int
sbuilder.append(100);
// 追加long
sbuilder.append(12345L);
// 追加StringBuilder对象
sbuilder.append(new StringBuilder("StringBuilder"));
// 追加StringBuilder对象。6表示被追加对象的起始位置(包括),13是结束位置(不包括)
sbuilder.append(new StringBuilder("STRINGBUILDER"), 6, 13);
// 追加StringBuffer对象。
sbuilder.append(new StringBuffer("StringBuffer"));
// 追加StringBuffer对象。6表示被追加对象的起始位置(包括),12是结束位置(不包括)
sbuilder.append(new StringBuffer("STRINGBUFFER"), 6, 12);
// 追加String对象。
sbuilder.append("String");
// 追加String对象。1表示被追加对象的起始位置(包括),6是结束位置(不包括)
sbuilder.append("0123456789", 1, 6);
sbuilder.append('\n');
// 追加Object对象。此处以HashMap为例
HashMap map = new HashMap();
map.put("1", "one");
map.put("2", "two");
map.put("3", "three");
sbuilder.append(map);
sbuilder.append('\n');
// 追加unicode编码
sbuilder.appendCodePoint(0x5b57); // 0x5b57是“字”的unicode编码
sbuilder.appendCodePoint(0x7b26); // 0x7b26是“符”的unicode编码
sbuilder.appendCodePoint(0x7f16); // 0x7f16是“编”的unicode编码
sbuilder.appendCodePoint(0x7801); // 0x7801是“码”的unicode编码
System.out.printf(sbuilder);
}

3.replace

public static void main(String[] args) {
        StringBuilder stringBuilder = new StringBuilder("0123456789");
        stringBuilder.replace(0,3,"ABCDE");
        System.out.println(stringBuilder);
        stringBuilder.reverse();
        System.out.println(stringBuilder);
		sbuilder.setCharAt(0, 'M');
		System.out.printf("sbuilder=%s\n", sbuilder);
		System.out.println();
}

4.delete

private static void testDeleteAPIs() {
System.out.println("------------------- testDeleteAPIs -------------------");
StringBuilder sbuilder = new StringBuilder("0123456789");
// 删除位置0的字符,剩余字符是“123456789”。
sbuilder.deleteCharAt(0);
// 删除位置3(包括)到位置6(不包括)之间的字符,剩余字符是“123789”。
sbuilder.delete(3,6);
// 获取sb中从位置1开始的字符串
String str1 = sbuilder.substring(1);
// 获取sb中从位置3(包括)到位置5(不包括)之间的字符串
String str2 = sbuilder.substring(3, 5);
// 获取sb中从位置3(包括)到位置5(不包括)之间的字符串,获取的对象是CharSequence对象,此处转型为String
String str3 = (String)sbuilder.subSequence(3, 5);
System.out.printf("sbuilder=%s\nstr1=%s\nstr2=%\nstr3=%s\n",sbuilder, str1, str2, str3);
}

5.index

/**
* StringBuilder 中index相关API演示
*/
private static void testIndexAPIs() {
System.out.println("-------------------------------- testIndexAPIs -----
---------------------------");
StringBuilder sbuilder = new StringBuilder("abcAbcABCabCaBcAbCaBCabc");
System.out.printf("sbuilder=%s\n", sbuilder);
// 1. 从前往后,找出"bc"第一次出现的位置
System.out.printf("%-30s = %d\n", "sbuilder.indexOf(\"bc\")",
sbuilder.indexOf("bc"));
// 2. 从位置5开始,从前往后,找出"bc"第一次出现的位置
System.out.printf("%-30s = %d\n", "sbuilder.indexOf(\"bc\", 5)",
sbuilder.indexOf("bc", 5));
// 3. 从后往前,找出"bc"第一次出现的位置
System.out.printf("%-30s = %d\n", "sbuilder.lastIndexOf(\"bc\")",
sbuilder.lastIndexOf("bc"));
// 4. 从位置4开始,从后往前,找出"bc"第一次出现的位置
System.out.printf("%-30s = %d\n", "sbuilder.lastIndexOf(\"bc\", 4)",
sbuilder.lastIndexOf("bc", 4));
System.out.println();
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值