`

第十三章 字符串

阅读更多
2013年8月1日 星期四 21时05分59秒

第十三章 字符串
        可以证明,字符串操作是计算机设计中最常见的行为

13.1 不可变String
        String类中每一个看起来会修改String值的方法,实际上都是创建一个全新的String对象。       

13.2 重载“+”与StringBuilder
         可以用javap命令来反编译class文件,查看代码是如何工作。
         例如:类Concatenation
                                   package chapter13;
public class Concatenation {
        public static void main(String[] args) {
                String mango="mango";
                String s="abc"+mango+"def"+47;
                System.out.println(s);
        }
}

                通过javap -c Concatenation后,得到如下字节码:
                     D:\Program Files\Java\jdk1.6.0_13\bin>javap -c Concatenation
Compiled from "Concatenation.java"
public class chapter13.Concatenation extends java.lang.Object{
public chapter13.Concatenation();
  Code:
   0:   aload_0
   1:   invokespecial   #8; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   ldc     #16; //String mango
   2:   astore_1
   3:   new     #18; //class java/lang/StringBuilder
   6:   dup
   7:   ldc     #20; //String abc
   9:   invokespecial   #22; //Method java/lang/StringBuilder."<init>":(Ljava/la
ng/String;)V
   12:  aload_1
   13:  invokevirtual   #25; //Method java/lang/StringBuilder.append:(Ljava/lang
/String;)Ljava/lang/StringBuilder;
   16:  ldc     #29; //String def
   18:  invokevirtual   #25; //Method java/lang/StringBuilder.append:(Ljava/lang
/String;)Ljava/lang/StringBuilder;
   21:  bipush  47
   23:  invokevirtual   #31; //Method java/lang/StringBuilder.append:(I)Ljava/la
ng/StringBuilder;
   26:  invokevirtual   #34; //Method java/lang/StringBuilder.toString:()Ljava/l
ang/String;
   29:  astore_2
   30:  getstatic       #38; //Field java/lang/System.out:Ljava/io/PrintStream;
   33:  aload_2
   34:  invokevirtual   #44; //Method java/io/PrintStream.println:(Ljava/lang/St
ring;)V
   37:  return
}
             由此可知,编译器创建了一个StringBuilder对象,用于构造最终的String。
             注解:dup指令是复制之前分配的java/lang/StringBuilder空间的引用并压入栈顶,invokevirtual指令通过22这个常量池入口需找到了java/lang/                                StringBuilder.append()方法,构造方法虽然找到了。但是必须还得知道是谁的构造方法,所以要将之前分配的空间的应用压入栈顶让                                     invokespecial命令应用才知道原来这个构造方法是刚才创建的那个引用的,调用完成之后将栈顶的值弹出。之后调用astore_1将此时的栈顶值弹出                          存入局部变量中去。

13.3 无意识的递归
                                    package chapter13;
import java.util.ArrayList;
import java.util.List;
/*@name InfiniteRecursion.java
* @describe  13.3 无意识的递归
* @since 2013-08-03 00:06
* @author 张彪
*/
public class InfiniteRecursion {
        public String toString(){
                return "InfiniteRecursion"+ this +"\n";  //this应该改为super.toString()
        }
        public static void main(String[] args) {
                List<InfiniteRecursion> list=new ArrayList<InfiniteRecursion>();
                for(int i=0;i<3;i++){
                        list.add(new InfiniteRecursion());
                }
                System.out.println(list.toString());
        }
}
//报错
/*Exception in thread "main" java.lang.StackOverflowError
        at java.lang.StringBuilder.append(StringBuilder.java:119)
        at java.lang.StringBuilder.<init>(StringBuilder.java:93)*/          

                        报错原因是由于编译器看到一个String对象之后跟一个“+”号,而后边的对象不是String类型,于是编译器试图将this转换成一个String。正式通过调用this上的                             toString()方法,于是发生了递归调用。
                        如果你这的想打印对象的内存地址,应该用Object.toString()方法。这才是负责此任务的方法。

13.4 String上的操作
                String对象的常用方法。
                String类的方法都会返回一个新的String对象。同时,如果内容没发生改变,String()方法只是返回指向原对象的引用而已。

13.5 格式化输出
        13.5.1 printf()
        13.5.2 System.out.format()
                J2SE5引入的format()方法。format()方法模仿于C的printf()方法。
                                        package chapter13;
public class SimpleFormat {
        public static void main(String[] args) {
                int x=5;
                float y=4.5f;
                System.out.println(x+" "+y);
                System.out.printf("%d,%f\n",x,y);
                System.out.format("%d,%f",x,y );
        }
}

        13.5.3 Formatter类 
        13.5.4 格式化说明符
                                      package chapter13;
import java.util.Formatter;
/*@name Receipt.java
* @describe  13.5.4 格式化说明符
* @since 2013-08-03 01:24
* @author 张彪
*/
//打印一个购物收据
public class Receipt {
        private double total=0;
        private Formatter f=new Formatter(System.out);
        public void printTitle(){
                f.format("%-15s %5s %10s\n","Item","Qty","Price");
                f.format("%-15s %5s %10s\n","----","----","----");
        }
        public void print(String name ,int qty, double price){
                f.format("%-15.15s %5d %10.2f\n", name,qty,price);
                total+=price;
        }
        public void printTotal(){
                f.format("%-15s %5s %10.2f\n","Tax","",total*0.06);
                f.format("%-15s %5s %10s\n","","","----" );
                f.format("%-15s %5s %10.2f\n","Total","",total*1.06 );
        }
       
        public static void main(String[] args) {
                Receipt t=new Receipt();
                t.printTitle();
                t.print("Jack's Magic Bean", 4, 4.25);
                t.print("Princess Peas", 3, 5.1);
                t.printTotal();
        }


Formatter提供了对空格与对其的强大功能。

        13.5.5 Formatter转换       
        13.5.6 String.format()

13.6 正则表达式
               正则表达式是一种强大而灵活的文本处理工具。
        13.6.1 基础
                \d 表示一位数字
                在 Java中,"\\"的意思是我要插入一个正则表达式的反斜线。
                -?\\d+  表示可能有一个负数,后面有多个数字

        13.6.2  创建正则表达式    
        13.6.3  量词
                量词描述一个模式吸收输入文本的方式
                        贪婪型:
                        勉强型:用?号来指定,
                        占有型:

                charSequence 接口。
                                                                                       
                                        package chapter13;
import java.util.Arrays;

/*@name IntegerMatch.java
* @describe  13.6 正则表达式
* @since 2013-08-03 10:24
* @author 张彪
*/
public class IntegerMatch {
        public void match1(){
                System.out.println("-123".matches("-?\\d+"));  //true
                System.out.println("-a3".matches("-?\\d+"));   //false
                //"+"在正则表达式有特殊的意义,所以这个地方要用转义
                System.out.println("+56".matches("(-|\\+)?\\d+")); //true
        }
        public void splitMethod(){
                String knights="Tree in the fores... wih ....a herring!";
                String regex1="\\w+";
                System.out.println(Arrays.toString(knights.split(" "))); //以" "进行分割
                System.out.println(Arrays.toString(knights.split("\\W"))); // "\W"意思是非单词字符 ,"\w"表示一个单词字符
                System.out.println(Arrays.toString(knights.split("n\\W+"))); //表示字母n后面跟着一个或多个非单词字符
                //split(regex, limit) 重载方法, 第二个参数为限制分割的次数
        }
        public void replaceMethod(){
                System.out.println("abc".replaceFirst("a|b|c","uu")); //uubc
        }
        //创建正则表达式
        public void createRegex(){
                for(String  patter:new String[]{"Rudolph","[rR]udolph","[rR][aeiou][a-z]ol.*","R.*"}){
                        System.out.println("Rudolph".matches(patter));
                }
        }
        public static void main(String[] args) {
                new IntegerMatch().createRegex();
        }
}
               
        13.6.4  Patter和Matcer
                Matcher.find()方法可以在CharSequence中查找多个匹配。
                                    package chapter13.string;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Finding {
        public void findMethod(){
                //模式  "\\w+" 将字符串划分为单词
                Matcher m=Pattern.compile("\\w+").matcher("Evening is full of the linet's wings");
                while(m.find()){
                        System.out.print(m.group()+"-");
                }
                System.out.println();
                int i=0;
                while(m.find(i)){
                        System.out.print(m.group()+"-");
                        i++;
                }
        }
        public static void main(String[] args) {
                new Finding().findMethod();
        }
}

                组(Groups)
                       组是用括号划分的正则表达式,可以根据组的编号来引用某个组。组号为0表示整个表达式。
                                               
                start()和end()
                Pattern标记
                                      package chapter13.string;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ReFlags {
        public static void main(String[] args) {
                Pattern p=Pattern.compile("^java", Pattern.CASE_INSENSITIVE|Pattern.MULTILINE);
                Matcher m=p.matcher("java has regex\nJava has regex\n" +
                                "JAVA has regex\n" +
                                "Regular exression are in Java");
                while(m.find()){
                        System.out.println(m.group()+"-");
                }
        }
}
/*java-
Java-
JAVA-*/
该例子中的模式将匹配以"java,Java,JAVA"等开头的行。注意group()方法只返回已匹配的部分。

        13.6.5 split()方法
                        split()方法将输入字符串断开成字符串对象数组,断开边界由下列正则表达式确定。
                                                package chapter13.string;
import java.util.Arrays;
import java.util.regex.Pattern;
public class SplitDemo {
        public static void main(String[] args) {
                String input="This!!unusal use!!of exclamation!!points";
                System.out.println(Arrays.toString(Pattern.compile("!!").split(input)));  //[This, unusal use, of exclamation, points]
                //第二个参数可以限制分割成字符串的数量
                System.out.println(Arrays.toString(Pattern.compile("!!").split(input,3))); //[This, unusal use, of exclamation!!points]
        }
}                       

        13.6.6  替换操作
                        replaceFirst(),replaceALl(),appendReplacement()..........
        13.6.7  reset()               
        13.6.8  正则表达式与Java I/O

13.7 扫描输入
           Scanner类
                 Scanner类在 Java SE5中新增的类。
                                             package chapter13.string;
import java.io.BufferedReader;
import java.io.StringReader;
import java.util.Scanner;
public class BetterRead {
        public static void main(String[] args) {
                Scanner scanner=new Scanner(new BufferedReader(new StringReader("Sir Robin of Camelot\n22 1.61803")));
                System.out.println(scanner.nextLine());   //Sir Robin of Camelot
                System.out.println(scanner.nextInt());    //22
        }
}
                                     
     13.7.1 Scanner定界符
                    Scanner默认情况下根据空白字符对输入进行分词。但是你也可以根据正则表达式进行指定自己所需要的定界符
                                          package chapter13.string;
import java.util.Scanner;
public class ScannerDelmiter {
        public static void main(String[] args) {
                Scanner scanner=new Scanner("12,34,56,78");
                scanner.useDelimiter("\\s*,\\s*");
                while(scanner.hasNext()){
                        System.out.println(scanner.nextInt());
                }
                       
        }
}

     13.7.2 用正则表达式扫描   
                             
13.8 StringTokenizer
        有了正则表达式和Scanner之后,StringTokenizer基本上可以废弃不用了。

13.9 总结 

       个人总结: 通过这章的学习,对正则表达式有了新的认识。。。。。。。。。。

       
               

                                                                                                    2013-08-06 0:47 记 @jinrongdajie31.xichengqu.beijing
                                                                                                                        
0
1
分享到:
评论

相关推荐

    Java编程思想第十三章字符串.pptx

    Java编程思想第十三章字符串.pptx

    第13章 字符串处理函数

    第13章主要讲解了字符串处理函数,涵盖了输入输出、复制和拼接等基本操作。以下是这些知识点的详细说明: 1. **输入和输出函数** - **putchar函数**:用于向标准输出设备(通常是显示器)打印一个字符。其函数原型...

    Python程序设计董付国(第二版)第4章字符串与正则表达式.pptx

    Python程序设计董付国第二版第四章字符串与正则表达式知识点总结 1. 字符串编码:ASCII、UTF-8、UTF-16、UTF-32、GB2312、GBK、CP936、base64等,了解不同编码格式的特点和应用场景。 2. Python字符串类型:Python...

    第03章 字符串用法.rar

    本章我们将深入探讨字符串的常见操作和使用技巧,以帮助你更好地理解和运用字符串这一重要的编程工具。 一、字符串定义与创建 字符串是由一个或多个字符组成的序列,通常用于存储文本信息。在很多编程语言中,如...

    java笔记字符串的应用

    Java 字符串应用笔记 在 Java 中,字符串是最基本的数据类型之一,理解字符串的应用是 Java 开发的基础。本篇笔记将详细介绍 Java 中 equals 和 == 的区别、字符串相关的几个函数介绍、String 和 StringBuffer 的...

    第五章 数组、字符串与类库

    本章主要探讨了数组,特别是字符串以及类库的使用。 一、数组 1. 一维数组 - 定义与创建: - 方式一:先声明数组变量,再创建数组对象。如 `int a[];` 后跟 `a = new int[3];` - 方式二:同时定义并创建数组,...

    第4章 python字符串.pptx

    值得注意的是,Python允许使用三引号('''或""")来创建多行字符串。 在字符串中,转义字符是一个重要的概念。转义字符以反斜线`\`开头,用于表示特殊功能或插入特殊字符。例如,`\n`用于插入一个换行符,`\t`插入...

    c语言函数库-第四章(字符串函数)[参照].pdf

    C语言函数库中的第四章主要聚焦于字符串处理函数,这些函数在软件开发中扮演着重要角色,特别是对于处理文本数据时。以下是对其中一些关键函数的详细解释: 1. `atof`:此函数用于将一个字符串转换为浮点型数值。它...

    POINTERS ON C 第九章编程练习16按照指定的格式字符串对一个数字字符进行格式化

    在第九章的“POINTERS ON C”中,编程练习16着重于使用格式化字符串来处理数字字符。这涉及到C语言的`printf`函数,它是`stdio.h`库中的一个关键组成部分,用于向标准输出(通常是控制台)打印格式化的数据。 `...

    优质Python教程 Python3.7从基础入门到精通进阶教程 第04章 熟练操作字符串 共10页.ppt

    第13章 基于thinter的GUI编程.ppt 第14章 Python的高级技术.ppt 第15章 数据库的应用.ppt 第16章 网络编程的应用.ppt 第17章 CGI程序设计.ppt 第18章 Web网站编程.ppt 第19章 经典游戏应用-开发弹球游戏.ppt 第20章 ...

    第6章-数组和字符串-练习题.pdf

    "数组和字符串-练习题.pdf" 本资源摘要信息是关于数组和字符串的练习题,共15道选择题,涵盖了数组和字符串的基本概念、数组下标、数组初始化、数组元素访问、字符串数组、数组拷贝等知识点。 一、数组基本概念 *...

    18.C#字符串和正则表达式参考手册 影印版

    第3章 字符串转换 68 3.1 ToString()方法 68 3.2 把数值表示为字符串 69 3.3 把日期和时间表示为字符串 74 3.4 把其他对象表示为字符串 76 3.5 用字符串表示字符串 78 3.6 把字符串转换为其他类型 79 3.6.1 把字符串...

    第12章04自定义字符串类_String.zip_综合类 自定义string

    在编程领域,自定义字符串类(如题目中的`_String`)是一种常见的实践,它允许开发者根据特定需求扩展或修改标准库中字符串类的功能。在本案例中,我们聚焦于如何构建一个综合性的自定义字符串类,以实现与C++标准库...

    《C Primer Plus》第六版 第十一章编程练习答案

    "《C Primer Plus》第六版 第十一章编程练习答案" 本资源摘要信息是关于《C Primer Plus》第六版 第十一章的编程练习答案,涵盖了多个与C语言相关的知识点。下面对这些知识点进行详细的解释和分析。 1. 输入字符串...

    第6章数组指针与字符串.

    本章主要讨论了数组、指针以及字符串的基本概念和使用方法。 数组是存储相同类型元素的集合,可以通过索引来访问每个元素。例如,数组A[10][5][15]是一个三维数组,它有10个元素,每个元素本身又是一个含有5个元素...

    c语言程序设计

    #### 一、第13章 字符串 **13.1 字符串字面量** - **定义**:字符串字面量(string literal)是由一对双引号括起来的一系列字符,用于表示字符串。 - **转义序列**: - 字符串字面量可以包含转义序列,这些序列...

    C++数据结构与算法

    第1章 C++面向对象程序设计  1.1 抽象数据类型  1.2 封装  1.3 继承  1.4 指针  1.4.1 指针与数组  1.4.2 指针与复制构造函数 ...第13章 字符串匹配 附录A 计算大O 附录B 标准模板库中的算法 附录C NP完整性

Global site tag (gtag.js) - Google Analytics