Java基本功练习十三(字符串和文本IO【相关概念、基本方法使用】)

        前面章节讲了类和对象,现在着重讲一下Java自带的字符串类,String类的各种方法的使用,可以看到在对字符串及相关的字符的处理时用String类的方法是非常方便的。

本篇博文注重讲解原理和相关方法的使用方法,并对容易出错的地方标红强调。下一篇博文将讲解相关的应用。

        在很多语言中字符串都被当作字符数组来处理,但是在Java中,字符串是一个对象。String类中有11个构造方法以及40多个处理字符串的方法。

        1.字符串的构造

        Stringmessage=new String(“Welcome to Java”);

        或String message=”Welcometo Java”;

        或char[]charArrary={‘G’,’o’,’o’,’d’,’D’,’a’,’y’};

        String message=newString(charArrary);

        理解以下三个概念(虽然它们之间区别可以忽略)

        String变量(存储的是对String对象的引用)、String对象(存储的是字符串的值)、字符串的值(统一码或ASCII码等信息)。

        2.不可变字符串及限定字符串

        不可变字符串:String对象是不可变的,它的内容是不能改变的。一旦创建,它们的内容不能修改。如String s =”Java”;s=”HTML”;不能改变字符串的值,只是将”HTML”的引用复制给s,第一个String对象仍然存在,只是不能再访问它了。

        限定字符串:对具有相同序列的字符串直接量使用同一个实例,这样的实例称为限定的。

        如String s1=”Wlecome to Java”;String s2=new String(“Welcome to Java”);Strings3=”Welcome to Java”;s1和s2不相等(不同的字符串对象),s1和s3是相等的(指向相同的限定字符串”Welcome to Java”)。

        3.字符串的比较方法

        之前讲过UML类图,下面就以类图的形式展示相关方法。


        如何比较两个字符串的内容相等?

        一般的思想是string1==string2,运算符“==”只是检测两个字符串是否指向同一个对象,但它不会告诉你它们的内容是否相同。应该用equals,如string1.equals(string2).

        另外compareTo也可用于字符串比较,如s1.compareTo(s2),如果等返回0,如果s1小于s2则返回第一个不同字符间的距离的相反数,大于则是正数,小于是负数。

        另外,如str.startsWith(prefix),str.endsWith(suffix).

        另外regionMatches也很重要,它的用法有两种:

        regionMatches(BooleanignoreCase,int toffset,String other,into offset,int len);和regionMatches(inttoffset,String other,into offset,int len);

        第一种可区分大小写字母,如果boolean ignoreCase出写true,表示不区分大小写,写false表示可区分大小写。而第二种方法认为大小写字母有区别。实际上第一种隐含了第二种的功能。

举例:

Strings1=”tsinghua”;String s2=”it is TsingHua”;

s1.regionMatches(0,s2,6,7);(false)s1.regionMatches(true,0,s2,6,7);(true)

        4.字符串长度、字符以及组合字符串

        

        使用String s = new String();时,s的长度为0.

使用一个字符串往往是知道它的直接量值的,如”Welcome to Java”.charAt(0)是正确的,它返回W。字符串的连接可用concat也可以用+号,但要实现连接功能至少要有一个操作数必须为字符串。

        5.提取字符串


        6.字符串的转换、替换和分隔


        其中split要重点介绍一下

        包含在java.lang.string.split中,它的功能是将一个字符串分割为子字符串,然后将结果作为字符串数组返回。格式为:stringObj.split([separator,[limit]]);其中stringObj是必选项,表示要被分解的String对象或文字。该对象不会被split方法修改。Separator为可选项,表示字符串或正则表达式对象,它表示了分割字符串时使用的是一个还是多个字符。如果忽略该项,返回包含整个字符串的单一元素数组。Limit为可选项,该值用来限定返回数组中的元素个数。值得注意的是:split方法的结果是一个字符串数组,在stringObj中每个出现separator的位置都要进行分解,separator不作为任何数组元素的部分返回。

        下面举个简单例子说明上述用法,并给出分析。截图如下所示:


        因为public String[] split(String regex)这里的参数名称是regex,也就是regularexpression(正则表达式)这个参数并不是一个简单的分隔用的字符,而是一个正则表达式,”.”在正则表达式中有特殊含义,因此我们在使用的时候必须进行转义。只需将:”.”改为”\\.”即可。

        7.依照模式匹配、替换和分隔

        可以通过某个指定的模式来匹配、替换和分隔字符串。

“Java is fun”.matches(“Java.*”)(true)

String s =”a+b$#c”.replaceAll(“[$+#]”,”NNN”);(aNNNbNNNNNNc)

String[]tokens=”Java,C?C#,C++”.split(“[.,:;?]”);(Java,C,C#,C++)     

        8.找出字符串中的某个字符或某个子串

        String类提供了几个重载的indexOf和lastIndexOf方法,它们可以找出一个字符或一个子串。


上述方法举例如下图所示:


         9.字符串与数组之间的转换

        字符串转换为数组:用toCharArrary()方法或getchars(intsrcBegin,int srcEnd,char[]dst,int dstBegin)。将下标从srcBegin到srcEnd-1的子串复制到字符数组dst中下标从dstBegin开始的位置。

        如char[] chars=”Java”.toCharArrary();(chars[0]是’J’,chars[3]是’a’)。

        如char[]dst={‘J’,’A’,’V’,’A’,’1’,’3’,’0’,’1’};”CS3720”.getChars(2,6,dst,4);这样,dst就变成了{‘J’,’A’,’V’,’A’,’3’,’7’,’2’,’0’};

        字符数组转换为字符串:构造方法String(char[])或方法valueOf(char[]).

        如String str=new String(new char[]{‘J’,’A’,’V’,’A’});

        如String str=String.valueOf(new char[]{‘J’,’A’,’V’,’A’});

        10.将字符和数值转换成字符串

        使用静态的valueOf方法能够将字符数组转换成字符串。可以使用valueOf方法的几种重载版本将字符和数值转换成字符串,这些重载的方法参数类型可以是char,double,long,int,float型。


        另外:可以用Double.parseDouble(str)或Integer.parseInt(str)将一个字符串转换成double型值或int型值。

        11.格式化字符串

String类中的静态format方法,可以创建一个格式化的字符串。语法为:String.format(format,item1,item2,…,itemk);这个方法很像printf方法,只是format方法返回一个格式化的字符串,而printf方法显示一个格式化的字符串。

如String s = String.format(“%5.2f”,45.556);创建一个”45.56”的字符串。

12.字符类Character

Java为每一种基本数据类型都提供了一个包装类。

这些类是Character、Boolean、Byte、Short、Integer、Long、Float和Double,所有这些类都在java.lang包中。它们把基本数据类型当作对象来处理,它们还包含一些有用的处理基本数据值的方法。

Character类有一个构造方法和多个确定字符类别(大、小写、数字等)的方法,已经大小写互相转换的方法。可以用一个char值创建一个Character对象。如Character character=new Character(‘a’);其UML类图如下所示:


13.StringBuilder、StringBuffer类

如前文所说,String对象一旦创建,它的值就确定了。而StringBuilder、StringBuffer是可以给它添加、插入或追加新的内容的,更加灵活。

一般来讲,能使用String类的地方都可以使用StringBuilder、StringBuffer。如果一个字符串不需要任何改变,则使用String类,而不使用StringBuilder和StringBuffer类。

除了StringBuffer中修改缓冲区的方法是同步的之外,两个类是很相似的。如果是多任务并发访问,就使用StringBuffer;而如果是单任务访问,使用StringBuilder会更有效。两个类的构造方法和其他方法几乎是完全一样的。本节讲StringBuilder,可以用StringBuffer替换StringBuilder,程序可以不经任何修改进行编译和运行。

StringBuilder类有3个构造方法和30多个用于管理生成器或修改生成器内字符串的方法。可以使用构造方法创建一个空字符串生成器或从一个字符串创建一个字符串生成器。

3个构造方法


30个方法

在字符串生成器末尾追加新的内容,特定位置插入新的内容,还可以删除或替换字符串生成器中的字符。所有这些修改方法都做了两件事:1)改变字符串生成器的内容;2)返回字符串生成器的引用。


StringBuilder类也包括几个重载的方法,可以将boolean、char、char数组、double、float、int、long、String类型值插入到字符串生成器。

    注意:字符串类型的变量可以进行直接打印输出的。

14.toString、capacity、length、setLength和charAt方法

StringBuffer类提供了许多其他处理字符串生成器和获取它的属性的方法。如下图所示:


注意:字符串的长度总是小于或等于生成器的容量。长度是存储在生成器中的字符串的实际大小,而容量是生成器的当前大小。如果有更多的字符添加到字符串生成器,超出它的容量,则生成器的容量会自动增加。在计算机内部,字符串生成器是一个字符数组,因此,生成器的容量就是数组的大小。如果超出生成器的容量,就用新的数组替换现有数组。新数组的大小为2X(前一个数组的长度+1)。

15.文件类File

存储在变量、数组和对象中的数据是暂时的,当程序终止时它们就会丢失。为了永久的保存程序中创建的数据,需要将它们存储到磁盘或光盘上的文件中。File类获取文件的属性以及删除和重命名文件,但不包含读写文件内容的方法。

在File类中删除的文件跑去哪里了??创建文件如果不指定路径,默认为当前工程的路径。

renameTo的使用,如果更改前后路径不一样,改前的文件将被删除。如果路径一样,则相当于将名字更改了。


16.文件输入和输出

File对象封装了文件或路径属性,但是它既不包括创建文件,也不包括从(向)文件读(写)数据的方法。为了完成I/O操作,需要使用恰当的Java I/O类创建对象。这些对象包含从(向)文件读(写)数据的方法。

使用PrintWriter写数据

Java.io.PrintWriter类可以用来创建一个文件并向文本文件写入数据。首先必须为一个文本文件创建一个PrintWriter对象,

如:PrintWriter output = new PrintWriter(filename);

然后可以调用PrintWriter对象上的print,println和printf方法向文件写入数据。如下是这个类的UML类图:


注意:必须使用close()方法关闭文件,否则数据就不能正确保存。

调用PrintWriter的构造方法可能会抛出某种I/O异常。Java强制要求编写代码来处理这类异常。在13章中将学习如何处理它。目前,只要在方法头声明中声明throws Exception即可。

使用Scanner读数据(读的文件必须存在)

为了从键盘中读取需要为System.in创建一个Scanner,如下:

Scannerinput = new Scanner(System.in);

而为了从文件中读取,就要为文件创建一个Scanner,如下所示:

Scannerinput = new Scanner(new File(filename));如下是UML类图:


注意:没有必要关闭输入文件,但这样做是一种释放被文件占用的资源的好办法。

Scanner如何工作

方法nextByte(),nextShort(),nextInt(),nextLong(),nextFloat(),nextDouble()和next()等都称为令牌读取方法(token-readingmethod),因为它们会读取用分隔符分隔开的令牌。默认情况下,分隔符是空格。可以使用useDelimiter(String regex)方法设置新的分隔符模式。

一个输入方法是如何工作的呢?

一个令牌读取方法首先跳过任意分隔符(默认情况下是空格),然后读取一个以分隔符结束的令牌。然后对应于nextByte(),nextShort(),nextInt(),nextLong(),nextFloat(),nextDouble(),这个令牌分别被自动地转换成一个byte,short,int ,long,float,double型的值。对于next()方法而言是无须做转换的。如果令牌和期望的类型不匹配,会抛出一个运行异常java.util.InputMismatchException.方法next()和nextLine()都会读取一个字符串,前者分隔符为空格,后者的分隔符为转行字符。

注意:令牌读取方法不能读取令牌后面的分隔符。如果在令牌读取方法之后调用nextLine(),该方法读取从这个分隔符开始,到这个行的行分隔符结束的字符。这个行分隔符也被读取,但是它不是nextLine()返回的字符串部分。


字符串和文本IO涉及到相当多的应用,使用起来也可以让很多问题简便不少,并且让程序逻辑思路更加清晰、排版美观等。得勤加练习!!

接下来的一篇博文专门讲相关应用,由于应用太过广泛,只是举几例以示说明。想要灵活运用,还是那句话,自己一个代码一个代码的敲出来,从错误中成长!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值