深入学习Java编程中的字符串的进阶使用_java

JAVA虽然是在C++基础上发展而来,但却对C++的许多缺陷有所改进,其中一个不得不提的就是字符串,我们知道,随着学习的深入,进入MFC时,当处理字符串或字符时,常会需要通过_T()宏将字符或字符串变成UNICODE型,否则,会在处理中出现BUG,而在JAVA中,字符char或存储在Character类中的字符,不是一个字节,而是2个字节,采用UNICODE,这是为了支持全世界上的所有字符。

        字符的序列组成字符串,有两种类型的字符串:一种是创建以后不需要修改的,称为字符串常量,在JAVA中,用String类存储;
     一种是创建以后需要对其进行修改的,称为字符串变量,在JAVA中,用StringBuffer类操作和管理。

 StringBuffer类

1、创建StringBuffer类对象

     StringBuffer类对象表示的是字符串变量(注意是"变量"),每一个StringBuffer类对象都是可以扩充和修改的字符串变量。以下是常用的StringBuffer类构造函数:

      (1)public StringBuffer()

       创建一个新的空的StringBuffer类的对象,其容量初值设置成16个字符(注意是16个字符)

   (2)public StringBuffer(int length)

       创建一个新的空的StringBuffer类的对象,其容量初值设置成length个字符

    (3)public StringBuffer(String str)

       创建一个新的StringBuffer类的对象,其内容为str的内容,容量设置成str长度再加16个字符 (注意:再加上16个字符)


2、StringBuffer类对象的常用方法

     (1)StringBuffer类对象的扩充

         StringBuffer类提供两组方法用来扩充StringBuffer对象所包含的字符,分别是:

        1)public StringBuffer append

                            (Object  obj)

          append方法用于扩充StringBuffer对象所包含的字符,该方法将指定的参数对象转化为字符串后,将其附加在原来的StringBuffer对象之后,并返回新的StringBuffer对象。附加的的参数对象可以是各种数据类型的,如int、char、String、double等。

2)public StringBuffer insert(

        int插入位置offset,参数对象类型,参数对象名)

    该方法将指定的参数对象转化为字符串后,将其插入在原来的StringBuffer对象中指定的位置,并返回新的StringBuffer对象。

    (2)StringBuffer类对象的长度与容量

    一个StringBuffer类对象的长度指的是它包含的字符个数;容量指的是被分配的字符空间的数量。

     1)public int length()

        该方法返回当前StringBuffer类对象包含的字符个数。

    2)public int capacity()

   该方法返回当前StringBuffer类对象分配的字符空间的数量。
(3)StringBuffer类对象的修改

   public void setCharAt(intindex,charch)

     该方法将当前StringBuffer对象中的index位置的字符替换为指定的字符ch。

    (4)字符串的赋值和加法

      字符串是在程序中要经常使用的数据类型,在Java编译系统中引入了字符串的赋值和加法操作。

   (5)其它方法类似String类的方法
3、利用StringTokenizer类分解字符串

StringTokenizer类位于java.util包中, 在使用该类时在程序开始加上

importjava.util.StringTokenizer或

importjava.util.*

StringTokenizer类

对于StringTokenizer类,其主要作用是将字符串按照给定的分割符进行分割,其功能和String类的split方法类似

1、StringTokenizer类的构造函数

(1)StringTokenizer(Stringstr)

         为给定的字符串str创建一个StringTokenizer对象,其分隔符默认设置为“\t\n\r\f”,亦即:空格、水平制表符tab、换行、回车、表格符

(2)StringTokenizer(String str,String delim)

              为给定的字符串str创建一个StringTokenizer对象,其分隔符为指定的字符串delim,默认不包含分隔符

 

3)StringTokenizer(String str,String delim,boolean returnDelims)

             为给定的字符串str创建一个StringTokenizer对象,其分隔符为指定的字符串delim,如果returnDelims为true,则创建的StringTokenizer对象中的每个字符串包含有分隔符,否则不包含分隔符

2、StringTokenizer类的常用方法

nIntcountTokens()
返回StringTokenizer对象中被分割后子字符串的个数
nBooleanhasMoreElements()
该方法的功能和hasMoreTokens()方法的功能一样
nBooleanhasMoreTokens()
检测StringTokenizer对象中是否包含分割好的子字符串,有则返回true,否则返回false
ObjectnextElement()

该方法具有nextToken()一样的功能,主要区别是它返回的不是String对象,而是一个Object对象

StringnextToken()

返回StringTokenizer对象中下一个分割好的子字符串

StringnextToken(String delim)

返回StringTokenizer对象中下一个分割好的子字符串,但是分隔符被重新设定为delim

n其实在有些编程语言中,比如C语言,其字符串就是由字符数组构成的,每个字符串的结尾用“\0”标志,但是在Java中却不是这样的。
n在Java中,字符串通常是作为String类的对象存在着,如:Strings=“I like Java!”,其中“Ilike Java!”就是一个对象。
所以说,Java中的字符串和字符数组是完全不相同的,和C语言中的字符串也是不一样的!

 

n为了方便字符串和字符数组的转换,在String类中提供了许多这样的构造函数和方法
n如构造函数String(char[] value)
n方法toCharArray()
方法valueOf(char[] data)

常量池

对于源程序中出现的字符串常量,当程序运行时,会统一保存到一个常量池中进行缓存。
对引用这些缓存在常量池中的字符串的变量进行比较,用==也会得到正确的结果。

但在运行时,对字符串的各种操作如+、substring等等,都是会产生新的字符串对象的。
但是强大的编译器会对字符串常量的拼接进行优化,诸如s3 = "hell" + "o"时,s3仍然会
指向常量池中的字符串。但对于变量的运算,总不能要求虚拟机执行诸如s1 + s2时还要
判断结果是否已在常量池中了吧。因此,要用equals而非==去判断两个字符串是否相等。

public static void main(String[] args) { 

 // String constants are put in constant pool.
 String s1 = "hello";
 String s2 = "hello";
 String s3 = "hell" + "o";
 System.out.println(s1 == s2);
 System.out.println(s1 == s3); 

 // Operation like +,substring on string create new one.
 String s4 = "hell";
 String s5 = s4 + "o";
 System.out.println(s1 == s5);
 System.out.println(s1.equals(s5)); 

 // substring has special handle on substring(0)
 String s6 = s1.substring(0);
 System.out.println(s1 == s6);
} 

测试代码s1、s2、s3的字节码:

   0:   ldc     #16; //String hello
   2:   astore_1
   3:   ldc     #16; //String hello
   5:   astore_2
   6:   ldc     #16; //String hello
   8:   astore_3

测试代码s4、s5的字节码:
  
   41:  ldc     #30; //String hell
   43:  astore  4
   45:  new     #32; //class java/lang/StringBuilder
   48:  dup
   49:  aload   4
   51:  invokestatic    #34; //Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
   54:  invokespecial   #40; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
   57:  ldc               #43; //String o
   59:  invokevirtual   #45; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   62:  invokevirtual   #49; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;

注意一点是substring方法,substring(0,3)是得到从字符0到2的字符串。这样设计的原因
也许是这样容易计算子串的长度,3-0=3。同时substring对于特殊参数有特别的优化处理:

public String substring(int beginIndex, int endIndex) {
 if (beginIndex < 0) {
  throw new StringIndexOutOfBoundsException(beginIndex);
 }
 if (endIndex > count) {
  throw new StringIndexOutOfBoundsException(endIndex);
 }
 if (beginIndex > endIndex) {
  throw new StringIndexOutOfBoundsException(endIndex - beginIndex);
 }
 return ((beginIndex == 0) && (endIndex == count)) ? this :
  new String(offset + beginIndex, endIndex - beginIndex, value);
} 

由此看出,String对象背后并没有什么神奇之处,对字节码有了些了解可以更好的理解它。
其实常量池中还保存类及其方法的很多信息,如包名、类名、方法签名等等,有兴趣可以
深入研究。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索java
字符串
,以便于您获取更多的相关知识。

时间: 2024-09-13 22:14:02

深入学习Java编程中的字符串的进阶使用_java的相关文章

在Java编程中使用正则表达式的基本方法_java

众所周知,在程序开发中,难免会遇到需要匹配.查找.替换.判断字符串的情况发生,而这些情况有时又比较复杂,如果用纯编码方式解决,往往会浪费程序员的时间及精力.因此,学习及使用正则表达式,便成了解决这一矛盾的主要手段.  大 家都知道,正则表达式是一种可以用于模式匹配和替换的规范,一个正则表达式就是由普通的字符(例如字符a到z)以及特殊字符(元字符)组成的文字模式,它 用以描述在查找文字主体时待匹配的一个或多个字符串.正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配.   自从jdk1

深入解析Java编程中面向字节流的一些应用_java

文件输入输出流 文件输入输出流 FileInputStream 和 FileOutputStream 负责完成对本地磁盘文件的顺序输入输出操作. [例]通过程序创建一个文件,从键盘输入字符,当遇到字符"#"时结束,在屏幕上显示该文件的所有内容 import java.io.*; class ep10_5{ public static void main(String args[]){ char ch; int data; try{ FileInputStream a=new FileI

Java编程中使用lambda表达式的奇技淫巧_java

为什么使用Lambda表达式先看几个例子: 第一个例子,在一个独立的线程中执行某项任务,我们通常这么实现: class Worker implements Runnable { public void run() { for (int i = 0; i < 100; i++) doWork(); } ... } Worker w = new Worker(); new Thread(w).start(); 第二个例子,自定义字符串比较的方法(通过字符串长度),一般这么做: class Lengt

详解Java编程中final,finalize,finally的区别_java

final:final可以让你控制你的成员.方法或者是一个类是否可被覆写或继承等功能,这些特点使final在Java中拥有了一个不可或缺的地位,也是学习Java时必须要知道和掌握的关键字之一. final成员 当你在类中定义变量时,在其前面加上final关键字,那便是说,这个变量一旦被初始化便不可改变,这里不可改变的意思对基本类型来说是其值不可变,而对于对象变量来说其引用不可再变.其初始化可以在两个地方,一是其定义处,二是在构造函数中,两者只能选其一. 下面程序很简单的演示了final的常规用法

完全解析Java编程中finally语句的执行原理_java

可不能小看这个简单的 finally,看似简单的问题背后,却隐藏了无数的玄机.接下来我就带您一步一步的揭开这个 finally 的神秘面纱.问题分析首先来问大家一个问题:finally 语句块一定会执行吗? 很多人都认为 finally 语句块是肯定要执行的,其中也包括一些很有经验的 Java 程序员.可惜并不像大多人所认为的那样,对于这个问题,答案当然是否定的,我们先来看下面这个例子. 清单 1. public class Test { public static void main(Stri

实例讲解Java编程中数组反射的使用方法_java

什么是反射"反射(Reflection)能够让运行于JVM中的程序检测和修改运行时的行为."这个概念常常会和内省(Introspection)混淆,以下是这两个术语在Wikipedia中的解释: 内省用于在运行时检测某个对象的类型和其包含的属性: 反射用于在运行时检测和修改某个对象的结构及其行为. 从它们的定义可以看出,内省是反射的一个子集.有些语言支持内省,但并不支持反射,如C++. 内省示例:instanceof 运算符用于检测某个对象是否属于特定的类. if (obj insta

深入解析Java编程中的boolean对象的运用_java

只能是true或false两个值之一的变量就是布尔(boolean)类型变量,true和false是布尔型直接量.你可以用下面的语句定义一个名称为state的布尔型变量: boolean state=true     该语句用true值对变量state进行了初始化.你也可以使用赋值语句为一个boolean型变量赋值.例如,语句, state=false     设置变量state的值为false.     目前,我们除了为布尔变量赋值外,还不能进行更多的操作,但正像你在下一章中将要看到的,布尔型

仔细触摸Java编程中的“文档”和“包”

编程 什么是包 Java中的包(Package)其实指的就是目录,它是为了更好地管理Java类(Class)和接口(Interface).Java语言的包可以被另一个Java开发包所使用.如果我们要引用某个包中的类,用import关键字来标明即可.比如: import java.util. date=new Date  提示:import java.util.表示java.util中的所有公有类和接口被引入到当前包.这里的匹配符可以调入多个类名. 常用的Java标准包 JDK为我

学习JAVA编程思想4的好方法

问题描述 跪求大神总结学习JAVA编程思想4的好方法. 解决方案 解决方案二:Java编程思想是很好的学习Java的材料,但对初学者来说有的地方不是能够轻易明白的.因为Java涉及的概念和技术非常广泛,建议先把基础夯实,比如类,接口,继承,多态等,这些有了基础后可以再深入学习正则表达式.线程.io等,一定要动手编写代码,并确实明白代码的执行逻辑.解决方案三:1.背把那些死知识背下来,复习巩固2.敲可以按书本例子课后题敲,对没掌握的可以重复敲3.测找其他题测试掌握情况,最好找SCJP题库的题,因为