第7章 String类

通过本章可以掌握String类的两种实例化方式与使用区别,掌握字符串相等比较的处理,掌握String类与字符串之间的联系,理解String类对象中常量池的使用特点,掌握String类的相关操作方法。
        在实际项目开发中,String类是一个必须使用的程序类,可以说是项目的核心组成类。在Java程序里所有的字符串都要求使用“"”进行定义,同时也可以利用“+”实现字符串的连接处理,但是对于String类实际上还有其自身的特点,本章将通过棘突的实例和概念进行String类的特点分析。

7.1 String类对象实例化

在Java中并没有字符串这一数据类型的存在,但是考虑到程序开发的需要,所以通过设计的形势提供了String类,并且该类的对象可以通过赋值的形式进行实例化操作。

范例:通过直接赋值的形式为String类对象实例化
public class StringDemo
{
public static void main(String args[])
{
String str="111";
System.out.println(str);
}
}

Java程序中使用""声明的内容都是字符串,本程序采用直接赋值的形势实现了String类对象实例化。

提示:观察String类的源代码实现
程序对于字符串的视线都是通过数组的形式进行保存的,所以对于String类的内部也会保存有数组内容,这一点可以通过String类的源代码观察到(源代码目录:JAVA_HOME\lib\src.zip)
JDK1.8以前String保存的是字符数组:
private final char value[];
JDK1.9以后String保存的字节数组
private final byte[] value;
字符串就是对数组的一种特殊包装应用,而对数组而言最大的问题就是长度固定。
String本身属于一个系统类,除了可以利用直接赋值的形势进行对象实例化之外,同时也提供了相应的构造方法进行对象实例化,构造方法如下:
String类构造方法public String(String str);
范例:通过构造方法实例化String类对象
public class StringDemo
{
public static void main(String args[])
{
String str=new String("ww");
System.out.println(str);
}
}

利用构造方法实例化String类对象可以采用标准的对象实例化格式进行处理操作,这种方法更为直观,其最终结果与直接赋值等同,但两者在本市上有区别的。

7.2 字符串比较

基本数据类型的相等判断可以使用Java中提供的==运算符来实现,可以进行熟知的比较,如果在String类对象上使用==比较的将不再是内容,而是字符串的堆内存地址。
范例:在String上使用==判断

public class StringDemo
{
public static void main(String args[])
{
String strA="111";
String strB=new String("222");
String strC=strB;
System.out.println(strA==strB);
System.out.println(strA==strC);
System.out.println(strB==strC);
}
}
程序执行结果前两个是false,最后一个是true,在本程序中在String类的对象上使用了==比较,通过结果发现对于同一个字符串采用不同方法进行String类对象实例化后,并不是所有String类对象的地址数值都是相同的,为了进一步说明,通过聚图的内存关系进行说明;

通过分析可以知道,在String类对象比较重,==的确可以实现相等的比较,但比较的并不是对象中的具体内容,而是对象地址数值。
提示:关于==在不同数据类型上的使用
在基本数据类型中==描述的是内容相同的判断,而在引用数据类型中==的作用还是数值比较,只不过此时的数值内容就是堆内存的地址。
范例:通过自定义类型使用==
class Dept{}
public class JavaDemo
{
public static void main(String args[])
{
Dept deptA=new Dept();
Dept deptB=new Dept();
Dept deptC=deptB;
System.out.println(deptA==deptB);
System.out.println(deptA==deptC);
System.out.println(deptB==deptC);
}
}

同样前两个结果为false,最后一个结果为true
对于字符串内容的判断,在String类中已经提供了相应equals()方法,只需要通过String类的实例化对象调用即可,该方法定义如下:
字符串内容相等判断(区分大小写):public boolean equals(OBject obj);
提示:关于equals()方法的使用:
在String类中定义的equals()方法里面需要接受的数据类型是object,调用String类的equals()方法秩序传入字符串即可。

范例:利用euqals()方法实现字符串内容比较:
public class StringDemo
{
public static void main(String args[])
{
String strA="lll";
String strB=new String("lll");
System.out.println(strA.equals(strB));
}
}

程序返回true,本程序采用两种实例化方式实现了String类实例化对象的定义,由于两个实例化对象保存的堆内存地址不同,所以只能够利用equals()方法实现相等判断。
提示:String类对象的这两种比较方法是初学者必须掌握的概念,两者的总结如下:
==是Java提供的关系运算符,主要功能是进行数值相等判断,如果用在了String对象上表示的是内存地址的比较。
equals是由String提供的一个方法,此方法专门负责字符串内容的比较。
在项目开发中,对于字符串的比较基本上都是通过内容是否相等的判断,所以主要使用equals()方法。

7.3 字符串常量

在程序中常量是不可被改变内容的统称,但由于Java中的处理支持,所以可以直接使用“"”进行字符串敞亮的定义。而这种字符串的常量,严格意义来讲是String类的匿名对象。

范例:观察字符串匿名对象

public class StringDemo
{
String str="lll";
//字符串常量是String类的匿名对象,可以直接调用String类中的方法
System.out.println("lll".euqals(str));
}

本程序最大的特点是直接利用字符串"lll"调用了equals()方法("lll".equals(str)),由于equals()方法是String类中定义的,而类中的普通方法只有实例化对象后才可以调用,那么就可以得出一个结论:字符串常亮就是String类的匿名对象。而所谓的String类对象直接赋值的操作,实际上就相当于将一个匿名对象设置了一个名字而以,但是唯一的区别是,String类匿名对象是由系统自动生成的。不在需要用户自己创建:
提示:实际开发中的字符串比较操作:
在实际开发过程中,有可能会有这样的需求:由用户自己输入一个字符串,而后判断其是否与指定的内容相同,而这时用户可能不输入任何数据,即内容为null
范例:观察问题
public class StringDemo
{
public static void main(String args[])
{
String input=null;//假设这个内容由用户输入
if(input.equals("AA"))
{
System.out.println("AAAA");
}
}
}

程序执行结果:Exception in thread main java.lang.NullPointerException at StringDemo.main(StringDemo.java:4)
由于没有数据输入,所以input的内容为null,而null对象调用方法的结果将直接导致错误信息提示NullPointerException,所以通过变更代码来帮助用户回避此问题。

范例:回避NullPointerException问题

public class StringDemo
{
public static void main(String args[])
{
String input=null;//假设这个内容
if("AA".equals(input))//如果输入的内容是“lll”,认为满足一个条件
{
System.out.println("AAA");
}
}
}

此时的程序直接利用字符串常亮来调用equals()方法,因为字符串常亮是一个String类的匿名对象,所以该对象永远不可能是null,也就不会出现NullPointerException,特别需要提醒读者的是,实际上equals()方法内部也存在对null的检查,对这一点有兴趣的读者可以打开Java类的源代码进行观察。

7.4 两种实例化方式比较

清除了String类的比较操作之后,下面就需要解决一个最为重要的问题。对于String类的对象存在两种实例化的操作方式,那么这两种方式有什么区别,在开发中应该使用哪一种方式进行;

1.分析直接赋值的对象实例化模式

在程序中只需要将一个字符串赋值给String类的对象就可以实现对象的实例化处理:
范例:直接赋值实例化对象:
public class StringDemo
{
public static void main(String args[])
{
String str="LLL";
}
}

此方式首先会在堆内存中分配“lll”的空间进行保存,并且在栈内存中地址赋值为该地址。
通过直接赋值的方式为String类对象实例化会开辟一块堆内存空间,而且对同意字符串的多次直接赋值还可以实现对堆内存的重用,即采用直接复制的方式进行String类对象实例化,在内容翔荣德情况下不会开辟新的堆内存空间,而会指向已有的堆内存空换个卡i按:

范例:观察直接赋值时的堆内存自动引用
public class StringDemo
{
String strA="LLL";
String strB="LLL";
String strC="BBB";
System.out.println(strA==strB);
System.out.println(strA==strC);
}

第一个结果是true,第二个结果是false
通过本程序的执行可以发现,由于使用了直接赋值实例化操作的方式,而且内容相同,所以即使没有直接发生对象的引用操作,最终两个String对象(strA,strB)也都指向了同一块堆内存空间。如果在直接赋值是内容与之前不一样,则会自动开辟新的堆内存(String strd="AAAA");

提示:关于字符串对象池:
实际上,在JVM的底层存在一个对象池(String只是对象池中保存的一种类型,此外还有其他多种类型,当代码中使用了直接赋值的定义定义了一个String类对象时,会将此字符串对象所使用的匿名对象入池保存,如果后续还有其他String类对象也采用了直接赋值的方式,并且设置了同样地内容,那么将不会开辟新的堆内存空间,而是使用已有的对象进行引用的分配,从而继续使用;

范例:通过代码分析字符串对象池操作

public class StringDemo
{
public static void main(String args[])
{
String strA="LLL";
String strB="BBB";
String strC="LLL";
System.out.println(strA==strB);
Ssytem.out.println(strA==strC);
}
}

第一个结果为false,第二个结果是true,本程序采用直接赋值的方式声明了3个String类对象,实质上,这些对象都保存在字符串对象池中(本质上保存在一个动态对象数组)中
对象池本质为共享设计模式的一种引用,关于共享模式的简单解释:好比在家中准备的工具箱一样,如果有一天需要用到螺丝刀,发现家中没有,那么肯定要去买一把新的吗,但是用完之后不可以丢掉,会将其放在工具箱中以备下次需要时使用,工具箱中的工具将为每一个成员服务:

2 分析构造方法实例化

如果要明确调用String类中的构造方法进行String类对象的实例化操作,那么一定要使用关键字new,而每当使用关键字new就表示要开辟新的堆内存空间,而这块堆内存空间的内容就是传入构造方法中的字符串数据,现在使用以下代码进行该操作的内存分析

范例:构造方法实例化对象
public class StringDemo
{
public static void main(String args[])
{
String str=new String("llll");
}
}

本程序使用一个字符串常量作为str对象的内容,并利用构造方法实例化了一个新的String类对象,本程序执行后的内存结构如上图,
        因为每一个字符串都是一个String类的匿名对象,所以首先在堆内存中开辟一块空间保存字符串“llll”,而后有使用关键字new,开辟另一块堆内存空间,而真正使用的是用关键字new开辟的堆内存,而之前定义的字符串常量开辟的堆空间将不会被任何的栈内存所指向,称为垃圾空间,并等待被GC回收,所以使用构造方法的方式开辟的字符串对象,实际上会开辟两块空间,其中一块空间将成为垃圾。
        除了内存的浪费之外,如果使用了构造方法实例化String类的对象,由于关键字new永远表示开辟新的堆内存空间,所以其内从不会保存在对象池中,

范例:构造方法实例化String类对象不自动入池保存

public class StringDemo
{
public static void main(String args[])
{
String strA=new String("LLL");
String strB="LLL";
System.out.println(strA==strB);
}
}

执行结果false
本程序首先利用构造方法开辟了一个新的String类对象,由于此时不会自动保存到对象池中,所以在使用直接赋值的方式声明String类对象后将开辟新的堆内存空间,因为两个堆内促男德地址不同,所以最终的地址判断结果为false。
        如果现在希望开辟的新内存数据也进入对象池保存,那么可以使用String类定义的一个手动入池的操作:
        手动保存到对象池:public String intern()
范例:String类对象手动入池
public class StringDemo
{
String strA=new String("AAA").intern();
String strB="AAA";
System.out.println(strA==strB);
}
程序返回true
本程序由于使用了String类的intern()方法,所以会将指定的字符串保存在对象池中,随后如果使用直接赋值的方式将会自动引用已有的堆内存空间,所以地址判断的结果为true:
提示:两种String类对象实例化区别
直接赋值(String str="字符串"):只会开辟一块堆内存空间,并且会自动保存在对象池中以供下次重复使用。
构造方法(String str=new String("字符串")):会开辟两块堆内存空间,一种一块空间将成为垃圾,并且不会自动入池,从而请尽量使用直接赋值的方式为String类对象实例化。

7.5 字符串常量池

Java中使用“"”就可以进行字符串实例化对象定义,如果处理不当就可能为多个内容相同的实例化对象重复开辟堆内存空间,这样会导致内存的大量浪费。为了解决这个问题,在JVM中提供了一个字符串常亮池(或者称为字符串对象池,其本质是一个动态对象数组),所以通过直接赋值实例化String类对象都可以自动保存在此常亮池中,以供下次使用。在Java中字符串常亮池一共分为两种:
静态常亮池:是指程序(*.class)在加载的时候会自动将此程序中保存的字符串、普通的常量、类、和方法等信息,全部进行分配。
运行时常量池:当一个程序(*.class)记载之后,有一些字符串通过String对象的形势保存后再实现字符串连接处理,由于String对象的内容可以改变,所以此时称为运行时常亮池
范例:静态常量池
public class StringDemo
{
public static void main(String args[])
{
String strA="AAABBB";
//使用+进行字符串链接,由于所有的内容都是敞亮,本质上表示一个字符串
String strB="AAA"+"BBB";
Ssytem.out.println(strA==strB)
}
}
执行结果true,本程序使用了两种方式定义了String类对象,由于在实例化strB对象时,所有参与链接的字符串都是常亮,所以在程序编译时会将这些常亮组合在一起进行定义,这样就与strA对象的内容相同,最终的结果就是继续使用字符串常亮池中提供的内容为strB实例化,不会开辟新的空间。

范例:运行时常量池
public class StringDemo
{
public static void main(String args[])
{
String logo="AAA";
String strA="BBBAAA";
String strB="BBB"+logo;
System.out.println(strA==strB);
}
}

本程序最大的特点是利用了一个logo的对象定义了要连接的字符串的内容,由于logo属于程序运行时才可以确定的内容,这就是的程序编译是无法知道logo的内容,所以strB对象无法从字符串常量中获得字符串引用。

7.6 字符串修改分析

String类对于数据的存储是基于数组实现的,数组本身属于定长的数据类型,这样的设计实际上就表明String类对象的内容一旦声明将不可直接改变,而所有的字符串对象内容的修改都是通过引用的变化来实现的。

范例:观察字符串修改

public class StringDemo
{
public static void main(String args[])
{
String str="AAA";//采用直接赋值的方式实例化String类对象
str+="BBB";//通过+链接新的字符串并改变str对象引用
str=str+"BBB";//通过+链接新的字符串并改变str对象引用
System.out.println(str);

}
}

本程序利用+实现了字符串内容的修改,但是这样的修改会导致垃圾内存的产生,通过上图可以发现,对字符串内容的修改,实质上是改变了引用关系,同时会产生垃圾空间。
范例:会产生许多垃圾空间的代码

public class StringDemo
{
public static void main(String args[])
{
String str="AAA";
for(int x=0;x<1000;x++)
{
str+=x;
}
System.out.println(str);
}
}

7.7 主方法组成分析

Java中的程序代码执行是从主方法开始的,并且主方法由许多部分组成,下面一一列出:
public :描述的一种访问权限,主方法是一切的开始点,开始点一定是公共的。
static:程序的执行是通过类名称完成的,所以表示此方法是由类直接调用的。
void:主方法是一切程序的起点,程序一旦开始执行是不需要返回任何结果的。
main:系统定义好的方法名称,当通过java命令解释一个类的时候会自动找到此方法名称。
String args[]:字符串的数组,可以实现程序启动的参数的接受。
参数传递的形势:java类名称 参数1 参数2 参数3
范例:验证参数传递,输入的必须是3个参数,否则程序退出
public class StringDemo
{
public static void main(String args[])
{
if(args.length==0)
{
System.out.println("Error 请输入启动参数");
System.exit(1);
}

for(String arg:args)
{
System.out.print(arg+"、");
}
}
}

程序执行结果
输入java StringDemo one two three:
本程序在执行时要求程序输入有相应的启动参数,如果没有启动参数会进行错误提示,并且直接结束执行,如果输入了参数会通过for循环的形势输出每一个参数的内容。
如果读者在输入参数的时候希望参数中间加有空格,如何“hello world”,可以通过“"”定义整体参数即可输入 java StringDemo "hello wold";

7.8 String类常用方法

String类作为项目开发中得到重要组成,除了拥有自身的特点之外,他还提供了大量的字符串操作方法:

7.8.1 JavaDoc文档简介

JavaDoc是Jva官方提供的应用程序编程借口(Application Programming interface,API)文档,开发者可以根据此文档来获取系统内裤的信息。
提示:关于JavaDoc的不从说明。
JavaDoc是在Java开发中接触到的最早的文档,该文档通过在线方式浏览,考虑到日后开发的需求,尽量阅读英文原版的信息。本次使用java10版本文档;
Overview (Java SE 10 & JDK 10 ) (oracle.com)
在JDK1.9之前,所有的Java中的常用类库都会在JVM启动的时候进行全部加载,这样会导致程序性能下降,在JDK1.9开始提供模块化设计,将一些程序类放在了不同的模块里面,所以在进行JavaDoc文档浏览时会发现上述模块定义。

每一个模块中优惠包含若干包,每个保重会定义不同的类,例如String类属于java.base谋爱中java.lang包中定义的类,打开相应的包后就可以发现String类的信息,
类的完整定义
类的相关说明信息
成员属性摘要:
构造方法摘要
方法摘要:

7.8.2 字符串与字符

字符串的基本组成单元是字符,在String类中提供有两者转换的处理方法:
 

No方法名称类型描述
1public String(char[] value)构造将传入的全部字符数组变为字符串
2public String(char[]value,int offset,int count)构造将部分字符数组变为字符串
3public char charAt(int index)普通获取指定索引位置的字符
4public char[] toCharArray()普通将字符串中的数据以字符数组的形式返回

范例:观察charAt()方法

public class StringDemo
{
public static void main(String args[])
{
String str="AAA";
char c=str.charAt(6);
System.out.println(c);
}
}

本程序中的字符串索引是从0开始的,本程序获取了索引位置为6的字符,实际上就是获取字符串的第7个数据
范例:字符串与字符数组转换

public class StringDemo
{
public static void main(String args[])
{
String str="AAA";
char [] result=str.toCharArray();
for(int x=0;x<result.length;x++)
{
result[x]-=32;
}
String newStr=new String(result);
System.out.println(newStr);
System.out.print(new String(result,0,4));
}
}

本程序中首先将字符串(为了操作方便,此时所有字符串全部都由小写字母组成)拆分为字符数组;其次使用循环分别处理数组中每一个字符的内容,最后使用String类的构造方法,将字符数组变为字符串对象。
        利用字符串与字符数组之间的转换形势也可以实现字符串的组成判断。例如,现在要求判断一个字符串中是否全部由数字所组成,首先将字符串变为数组,其次判断字符是否在数字编码范围内(0-9)

范例判断字符串组成是都全部是数字

public class StringDemo
{
public static void main(String args[])
{
System.out.println(isNumber("AAA")?"由数字组成":"不是有数字组成");
}
}

public static boolean isNumber(String str)
{
char [] result=str.toCharArray();
for(int x=0;x<result.length;x++)
{
if(result[x]<'0'||result[x]>'9')
{
return false;
}
}

return true;
}

在程序在主类中定义了isNumber()方法,所以此方法可以再主方法中调用。在isNumber()方法中为了实现判断,首先将字符串转换为字符数组;其次采用循环的方式判断每一个字符是否是数字,如果有一位不是则范围false。

7.8.3 字符串与字节

字节使用byte描述,字节一般主要用于数据的传输或者进行编码转换,String类就提供了将字符串变为字节数组的操作,目的就是为了方便传输以及编码转换:
 

No方法名称类型描述
1public String (byte[] bytes)构造将全部字节数组变为字符串
2public String(byte [] bytes,int offset,int length)普通将字符串转为字节数组
3public byte[] getBytes()普通将字符串转为字节数组
4public byte[] getBytes(String charsetName) throws UnsupportedEncodingException普通编码转换

范例:字符串与字节转换

public class StringDemo
{
public static void main(String args[])
{
String str="AAAA";
byte data[]=str.getBytes();
for(int x=0;x<data.length;x++)
{
data[x]-=32;
}

System.out.println(new String(data));
System.out.println(new String(data,0,5));
}
}

本程序利用字节数据类型实现了字符串小写字母转大写字母的操作,首先将字符串利用getBytes()方法变为字节数组:其次修改数组中每个元素的内容,最终利用String的字符串将修改后的字节数组全部或部分变为字符串。

7.8.4 字符串比较

equals()是最为常用的一个字符串现象等判断的比较方法,使用该方法进行比较时智能后判断两个字符串的内容是否完全一致,而除此方法外,也可以使用如下方法进行更多的比较判断:
范例:观察大小姐比较
public class StringDemo
{
public static void main(String args[])
{
String str="AAA";
System.out.println("aaa".euqals(str));
System.out.println("aaa".equalsIgnoreCase(str));
}
}

执行结果false与true
本程序首先定义了一个String类对象;其次利用equals()方法进行比较,可以发现equals()是区分大小写的,比较结果为false,而使用equalsIgnoreCase()方法比较是不区分大小写的,结果为true。
        equals()和equalsIgnoreCase()两种方法只适用于判断内容是否相等,如果要想比较两个字符串的大小,那么必须使用compareTo()方法完成,这个方法返回int型数据,这个int型数据有三种结果:大于0,小于0和等于0
范例:观察compareTo()方法
public class StringDemo
{
public static void main(String args[])
{
String strA="aaa";
String strB="AAa";
System.out.println(strA.compareTo(strB));
System.out.println(strB.compareTo(strA));
System.out.println("Hello".compareTo("Hello"));
System.out.println(strA.compareToIgnoreCase(strB));
}
}

使用compareTo()方法进行大小比较时,会依次比较两个字符串中每个字符的编码内容,并且依据编码的差值最终比较结果,compareToIgnoreCase()方法会忽略大小写

7.8.5 字符串查找

范例:查找子字符串时是否存在

public class StringDemo
{
public static void main(String args[])
{
String str="LLL";
System.out.println(str.contains("L"));
System.out.println(str.contains("hello"));
}
}

contains是从JDK1.5之后新增加的一个方法,但是在JDK1.5之前类似的判断只能同伙indexOf()方法实现,该方法会进行子字符串索引的查找。最终根据返回结果来判断子字符串是否存在
范例:使用indexOf()方法判断

public class StringDemo
{
public static void main(String args[])
{
String str="AAA";
System.out.println(str.indexOf("AA"));
System.out.println(str.indexOf("hello"));
if(str.indexOf("AA")!=-1)
{
System.out.println("要查询的子串存在");
}
}
}

本程序利用indexOf()方法实现子字符串索引的查找,如果可以找到指定内容就会返回索引数据,如果没有找到就会返回-1

提示:关于contains()方法的说明
String类中的contains()方法是基于indexOf()实现的,源代码如下:
public boolean contains(CharSequence s)
{
return indexOf(s.toString())>=0;
}

indexOf()方法在进行字符串查找时,采用的是由前往后顺序查找的,如果需要改变顺序,则可以使用lastIndexOf()方法实现。

范例:使用lastIndexOf()查找
public class StringDemo
{
public static void main(String args[])
{
String str="AAB";
System.out.println(str.lastindexOf("B"))
}
}

本程序通过lastIndexOf()由后向前检索字符“.”的索引,返回了第一个查找到的索引为主。

范例:判断是否以指定的字符串开头或结尾

public class StringDemo
{
public static void main(String args[])
{
String str="**@@AAAAA";
System.out.println(str.startWith("*"));
System.out.println(str.startWith("**",2));
System.out.println(str.endWith("AA",2));
}
}

7.8.6 字符串替换

在String类中提供有字符串的替换操作,即可以将指定的字符串内容进行整体替换:
 

No.方法名称类型描述
1public String replaceAll(String regex,String replacement)普通全部替换
2public String replaceFirst(String regex,String replacement)普通替换首个

范例:观察字符串替换

public class StringDemo
{

public static void main(String args[])
{
String str="AAA";
System.out.println(str.replaceAll("A","B"));
System.out.println(str.replaceFirst("A","B"));
}

}

本程序利用replaceAll()与replaceFirst()两个方法实现了全部以及首个内容的替换,特别需要注意的是,这两个方法都会返回替换完成后的新字符串内容。

7.8.7 字符串拆分

字符串拆分操作是按照一个指定的字符串标记,将一个完整的字符串分割为字符串数组,如果要完成拆分操作:
 

No方法名称类型描述
1public String[] split(String regx)普通按照指定的字符串进行全部拆分
2public String[] split(String regex,int limit)普通按照指定的字符串进行部分拆分,最后的数组长度由limit决定,即前面拆,后面不拆

范例:字符串全拆分

public class StringDemo
{
public static void main(String args[])
{
String str="AAA";
String result[]=str.split(" ");
for(int x=0;x<result.length;x++)
{
System.out.println(result[x]);
}
}
}

本程序将一个字符串按照空格进行全部拆分,最后将一个完整的字符串拆分成4个字符串,并且将其保存在String类的对象数组中。

提示:如果split()方法的参数为空字符则表示根据每个字符拆分。
在进行字符串拆分时,如果split()方法中设置的是一个空字符串,那么就表示全部拆分,即将整个字符串变为一个字符串数组,而数组的长度就是字符串的长度。
范例:字符串全部拆分

public class StringDemo
{
public static void main(String args[])
{
String str="AAA";
String result[]=str.split(" ");
for(int x=0;x<result.length;x++)
{
System.out.println(result[x]);
}
}
}

范例:拆分为指定长度的数组
public class StringDemo
{
public static void main(String args[])
{
String str="AAA";
String result[]=str.split(" ",2);
for(int x=0;x<resultlength;x++)
{
Sytsem.out.println(result[x]);
}
}
}

本程序在进行拆分时设置了拆分的个数,所以之江全部的内容拆分为两个长度的字符串对象数组。

注意:要避免正则表达式的影响,可以进行中转义操作

实际上,split()方法的字符串拆分是否能正常进行斗鱼正则表达式的操作有关,所以有些时候会出现无法拆分的情况,例如,现在给一个IP地址(192.168.1.2),那么首先想到的肯定是根据“.”进行拆扥,而如果直接使用“.”是不可能正常拆分的

范例:错误的拆分操作

public class StringDemo
{
String str="192.168.1.2";
String result []=str.split(".");
for(int x=0;x<result.length;x++)
{
System.out.println(result[x]);
}
}

此时程序不能够正常执行,而想要正常执行,必须要对拆分的“.”进行转义,在JAVA中进行转义要使用“\\”进行描述,在JAVA中要使用\\表示一个\;
范例:正确的拆分操作:
public class StringDemo
{
public static void main(String args[])
{
String str="192.168.1.2";
String result[]=str.split("\\.");
for(int x=0;x<result.length;x++)
{
System.out.println(result[x]);
}
}
}

在实际开发中,拆分操作是非常常见的,因为经常会传递一组数据到程序中进行处理,例如:现在有如下的一个字符串:“张三:20|李四:21|王五:22”当接收到此类数据时进行数据拆分。
范例:复杂拆分

public class StringDemo
{
public static void main(String args[])
{
String str="张三:20|李四:21|王五:22";
String result[]=str.split("\\|");
for(int x=0;x<result[x].length;x++)
{
String temp[]=result[x].split(":");
System.out.println("姓名:"+temp[0]+"年龄"+temp[1]);
}
}
}

本程序首先使用了|进行了拆分,其次在每次循环中有使用:继续进行拆分,最终取得了姓名与年龄数据。在实际开发中,这样的数据传递形式很常见,所以一定要掌握。

7.8.8 字符串截取

public class StringDemo
{
public static void main(String args[])
{
String str="AAAAAAA";
System.out.println(str.substring(4));
System.out.println(str.substring(4,8));
}
}
substring()方法存在重载操作,所以他可以返回两种截取结果,一种是从指定位置截取到结尾;另一种是设置截取的开始索引与结束索引。截取完成后substring()方法会返回截取的结果。

范例:通过字符串索引确定截取范围

public class StringDemo
{
public static void main(String args[])
{
String str="LLLL-photo-LXH.jpg";
int beginIndex=str.indexOf("-",str.indexOf("photo"))+1;
int endIndex=str.lastIndexOf(".");
System.out.println(str.substring(beginIndex,endIndex));
}
}

本程序在实际项目开发中是较为常见的一种设计思想,即通过既定的结构进行字符串的保存,这样就可以通过一些指定的内容作为索引标记,从而获取所需要的数据信息。

7.8.9 字符串格式化

为了吸引更多的传统开发人员,从JDK1.5开始Java提供了格式化数据的处理操作,类似于C语言中格式化输出语句,可以利用占位符实现数据的输出。常用的占位符有字符串(%s)、字符(%c)、整数(%d)、小数(%f)等,格式化字符串方法如下:
public static String format(String format,各种类型..args);
范例:格式化字符串

public class StringDemo
{
public static void main(String args[])
{
String name="张三";
int age=18;
double score=98.19;
String str=String.format("姓名%s、年龄:%d、成绩:%5.2f"name,age,score);
System.out.println(str);
}
}

String类中的format()方法是一个静态方法,可以直接用类名称进行调用,使用各种占位符,并利用可选参数配置对应内容即可实现字符串格式化处理。
提示:format()方法同c语言的printf()函数功能类似
当看到printf()方法名称的时候应该首先想到的是C语言中的输出,现在Java中也具备了同样地功能,而输出的时候可以使用一些标记来表示要输出的内容。例如字符串%s,整数%d,小数%f,字符%c等,之所以有这样的输出,其实目的在于抢夺C语言的开发人员市场。

7.8.10 其他操作方法

在String类中提供了多种处理方法,除了之前给定的几类外,也可以利用自身的方法实现长度计算、空字符串判断、大小写转换等操作:
范例:字符串连接

public class StringDemo
{
public static void main(String args[])
{
String strA="AAA";
String strB="AAA".concat("BBB").concat("CCC");
System.out.println(strB);
System.out.println(strA==strB);
}
}

concat()的操作形式与+的作用类似,但是需要注意的是,concat()方法在每一次进行字符串连接后都会返回一个新的实例化对象,属于运行时常亮,所以与静态字符串敞亮的内存地址不同。
        在字符串定义的时候“""”和null不是一个概念,一个表示有实例化对象,一个表示没有实例化对象,而isEmpy()主要是判断字符串的内容,所以一定要在有实例化对象的时候调用。

范例:判断空字符串
public class StringDemo
{
String str=" ";
System.out.println(str.isEmpty());
System.out.println("AAA".isEmpty());
}

true,false

本程序利用isEmpty()判断了字符串的内容是否为空,当字符串实例化后并且设置内容会返回true。

范例:观察length()与trim()方法
public class StringDemo
{
public static void main(String args[])
{
String str="Java";
System.out.println(str.length());
String trimStr=str.trim();
System.out.println(str);
System.out.println(trimstr);
System.out.println(trimStr.length());
}
}

本程序利用trim()方法去除字符串前后空格。在实际项目中要求用户输入一些数据信息(登录密码用户名和密码)就可以利用此方式来处理输入数据,避免由于错误出入多余的空格而出现错误。

提示:关于length的说明
有许多初学者容易把String类中的length()方法(String对象.length())与数组中的length(数组对象.length)属性混淆,在这里一定要提醒读者的是:String中取得字符串长度使用的是length()方法,只要是方法就必须要有(),而数组中没有length()方法,只有length属性。

利用编码的数字加减处理可以实现大小写字母的转换操作。针对字符数组大小写转换,传统开发一般会采用循环的方法,该方法比较麻烦,为此String类提供有大小写转换,传统开发一般会采用循环的方法,该方法会比较麻烦,为此String类提供有大小写转换的方法,利用此方法可以方便的实现字幕的大小写转换(非字母不做处理)
范例:大小写转换

public class StringDemo
{
public static void main(String args[])
{
String str="AAA";
System.out.println(str.toUppercase());
System.out.println(str.toLowercase());
}
}

在本程序中定义的字符串之中包含有非字母,而执行后可以发现,所有的非字母均没有做任何处理,只是在字母上实现了大小写的转换。
        在String类中提供了大部分常见的字符串处理操作方法,但是在世纪使用中经常会出现一些特殊的要求:例如将字符串首字母大写,那么这时就需要开发者自行设计。

       范例:实现首字母大写功能

class StringUtil
{
public static String initcap(String str)
{
if(str==numm||"".equals(str));
return str;
if(str.length()==1)
return str.toUppercase();
return str.substring(0,1).toUpperCase()+str.substring(1);
}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值