资讯专栏INFORMATION COLUMN

《Java编程思想》笔记13.字符串

since1986 / 1113人阅读

摘要:的构造器经过重载可以接受多种输出目的地,不过最常用的还是和。组号为表示整个表达式,组号表示被第一对括号括起的组,依此类推。有多个重载的构造器,可以接受和对象。

点击进入我的博客

字符串操作是计算机程序设计中最常见的行为

13.1 不可变String

String底层是由char[]实现的,是不可变的。
看起来会改变String的方法,实际上都是创建了一个新的String对象,任何指向它的引用都不可能改变它本身的值。

13.2 重载“+”与StringBuilder

重载操作符的意思是,一个操作符被用于不同的类时,被赋予类特殊的含义(String++=是Java中仅有的两个重载过的操作符,而且Java不允许程序员重载操作符)。
由于String的不可变性,如果你通过多个String相加生成一个String的时候,就需要产生多个中间对象,这造成了一定的效率问题。

StringBuilder的好处

使用String对字符串进行操作时,编译器会自动帮你转成StringBuilder来进行操作

StringBuilder来操作字符串,编译后的代码通常会更加简单,效率更高

如果字符串比较简单,可以使用String让编译器为你构造最终的字符串结果;如果要在循环中使用字符串,那么最好自己创建一个StringBuilder

13.3 无意识的递归
    @Override
    public String toString() {
        return "Test" + this;
    }

上述代码中,由于字符串在拼接的时候会自动调用toString()方法,所以会无意思造成递归。
如果你想打印对象的内存地址,应该调用Object.toString()方法

13.4 String上的操作

13.5 格式化输出 13.5.1 System.out.printf()

System.out.printf("%d%n", 123)这种输入方式来自于C,使用特殊的占位符来表示数据将来的位置,这些占位符称作格式修饰符

13.5.2 System.out.format()

System.out.printf()是相同的。

13.5.3 Formatter类

在Java中,所有新的格式化功能都由java.util.Formatter类处理。
Formatter的构造器经过重载可以接受多种输出目的地,不过最常用的还是PrintStreamOutputStreamFile

13.5.4 格式化说明符

%[argument_index$] [flags] [width] [.precision] conversion

可选的argument_index是一个十进制整数,用于表明参数在参数列表中的位置。第一个参数由1$引用,第二个参数由2$引用,依此类推(不要忘记$)。

可选flags是修改输出格式的字符集。有效标志集取决于转换类型。

可选width是一个非负十进制整数,表明要向输出中写入的最少字符数,不足则用空格代替。默认数据是右对齐,可以通过-实现左对齐。

可选precision是一个非负十进制整数,通常用来限制最大字符数。特定行为取决于转换类型。

所需conversion是一个表明应该如何格式化参数的字符。给定参数的有效转换集取决于参数的数据类型。

13.5.5 Formatter转换

13.5.6 String.format()

该方法可以接受Formatter.format()方法一样的参数,但返回一个String对象。

13.6 正则表达式

正则表达式是一种强大而灵活的文本处理工具。使用正则表达式,我们能够以编程的方式,构造复杂的文本模式,并对输入的字符串进行搜索。一旦找到了匹配这些模式的部分,你就能够随心所欲地对它们进行处理。

13.6.1 基础

正则表达式就是以某种方式来描述字符串。

Java和其他语言对反斜线的处理不同

正常反斜线:我们需要的就是一个单纯的反斜线,但Java(包括其他语言)中,反斜线也被用来当作转义字符,所以不能直接使用

文艺反斜线:第一个反斜线表示转移,第二个表示正常的反斜线

Java二逼反斜线:在正则表达式中,反斜线也需要转义,这是如果要插入一条反斜线这需要这种写法。四个反斜线的作用其实是两两一组,第一组的反斜线作为转义符,第二组的反斜线是正常要插入的反斜线。

String中内建的正则匹配方法

String#matches()

String#split()

String#replaceFirst()

String#replaceAll()

13.6.2 创建正则表达式

正则表达式完整构造子列表,请参考java.util.regex.Pattern

字符

字符类

逻辑操作符

边界匹配符

13.6.3 量词
量词:描述了一个模式吸收输入文本的方式:

贪婪型:默认设置,贪婪表达式会为所有可能的模式发现尽可能多的匹配,导致此问题的一个经典理由就是假定我们的模式仅能匹配第一个可能的字符组,如果它是贪婪的,那么它会继续往下匹配;

勉强型:在贪婪型基础上添加?,这个量词匹配满足模式所需的最少字符数,又称作最少匹配;

占有型:在贪婪型基础上添加+,目前这种类型的量词只有在Java中才可用并且也更高级,当正则表达式被应用于字符串时,它会产生相当多的状态以便在匹配失败时可以回溯,而占有型量词并不保存这些中间状态,因此它们可以防止回溯,它们被用来防止正则表达式失控,因此可以让正则表达式执行起来更有效。

13.6.4 Pattern和Matcher

由于String类功能有限,所以可以通过java.util.regex包下的类实现更加复杂的功能

一般使用方法
    // 1.构建Pattern对象
    Pattern pattern = Pattern.compile("1[0-9]{10}");
    // 2.构建Matcher对象
    Matcher matcher = pattern.matcher("18888888888");
    // 3.使用Matcher方法
    System.out.println(matcher.matches());
Pattern方法
    // 构建Pattern对象
    Pattern pattern = Pattern.compile(regex);
    // 将字符串按照正则表达式分割
    pattern.split("18888888888");
    // 生成Matcher对象判断是否匹配
    pattern.matcher("18888888888");
    // 直接验证正则表达式和字符串是否匹配
    Pattern.matches("1[0-9]{10}", "18888888888");
Pattern标记

Pattern类的compile()方法还有另一个版本,它接受一个标记参数数,以调整匹配的行为:
Pattern Pattern.compile(String regex,int flag);。其中的flag来自以下Pattern类中的常量:

Matcher方法

组是用括号划分的正则表达式,可以根据组的编号来引用某个组。组号为0表示整个表达式,组号1表示被第一对括号括起的组,依此类推。因此在下面这个表达式:A(B(C))D中有三个组,组0是ABCD,组1是BC,组2是C。

    // 整个字符串是否满足表达式
    matcher.matches();
    // 判断字符串中是否包含表达式
    matcher.lookingAt();
    // 遍历字符串
    matcher.find();
    matcher.find(int start);
    // 返回前一次匹配的结果
    matcher.group();
    matcher.groupCount();
    // 返回前一次匹配操作中寻找到的组的起始索引
    matcher.start();
    // 返回前一次匹配操作中寻找到的组的最后一个字符加一的值
    matcher.end();
    // 替换所有
    matcher.replaceAll();
    // 替换第一个
    matcher.replaceFirst();
    // 渐进式的替换
    matcher.appendReplacement();
    // 将现在Matcher用于一个新的字符串
    matcher.reset();
13.7 扫描输入

到日前为止,从文件或标准输入读取数据还是一件相当痛普的事情。终于,Java SE5新增了Scanner类,它可以大大减轻扫描输入的工作负担。
Scanner有多个重载的构造器,可以接受FilePathInputStreamStringReadable对象。Readable是Java SE5中新加入的一个接口,表示“具有read()方法的某种东西”。

13.7.1 Scanner的定界符

在默认的情况下,Scanner根据空白字符对输入进行分词,但是你可以用正则表达式指定自己所需的定界符:scanner.useDelimiter();。还有一个delimiter()方法,用来返回当前正在作为定界符使用的Pattern对象。

13.7.2 用正则表达式扫描
    Scanner scanner = new Scanner(System.in);
    while (scanner.hasNext("(d+)@(w+).(w+)")) {
        scanner.next("(d+)@(w+).(w+)");
        MatchResult result = scanner.match();
        System.out.println("号码:" + result.group(1));
        System.out.println("域名:" + result.group(2));
        System.out.println("后缀:" + result.group(3));
    }

Scanner可以接受Pattern作为参数,可以扫描复杂的数据。
配合正则表达式扫描时要注意:它仅仅针对下一个输入分词进行匹配,如果你的正则表达式中含有定界符,那永远都不可能匹配成功。

13.8 StringTokenizer

已过时!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/72333.html

相关文章

  • Java编程思想笔记3.操作符

    摘要:自动拆箱用赋值运算符把一个包装类赋值给一个基本类型变量,或者是在包装类进行数值运算时。指数计数,表示的幂按位操作符可以把值看成单比特值对待,的操作相同,但是不能用于布尔值。移位操作符高位包括符号位舍弃,低位补零。 点击进入我的博客 3.1更简单的打印语句 System.out.println(imbug); 通过编写一个小类库,并通过import static该方法来实现简化打印(基...

    wpw 评论0 收藏0
  • Java编程思想笔记11.持有对象

    摘要:迭代器通常被成为轻量级对象创建它的代价很小。与迭代器可以用于数组和所有对象,之所以能够工作,是因为继承了接口。 点击进入我的博客 我觉得本章名字改成容器似乎更好理解,持有对象让人感到一头雾水我们需要在任意时刻和任意位置创建任意数量的对象,所以依靠创建命名的引用来持有对象已经满足不了需求。Java可以用数组和其他容器类来(List、Set、Queue、Map)来解决这个问题,不同的容器...

    newtrek 评论0 收藏0
  • Java编程思想笔记12.通过异常处理错误

    摘要:一旦异常被抛出,就表明错误已无法挽回,也不能回来继续执行。这种在编译时被强制检查的异常称为被检查的异常。通过获取原始异常。构造器对于在构造阶段可能会抛出异常,并要求清理的类,最安全的做法是使用嵌套的子句。 点击进入我的博客 Java异常处理的目的在于通过使用少于目前数量的代码来简化大型、可靠的程序的生成,并且通过这种方式可以使你更自信:你的应用中没有未处理的错误。 12.1 概念 异...

    Vultr 评论0 收藏0
  • Java编程思想笔记4.控制执行流程

    摘要:在初始化和步进控制部分,可以用一系列由逗号分割的语句,而且那些语句会独立执行。和都表示无限循环语法数组等关键词有两个方面的用途一方面指定一个方法返回什么值另一个方面指定当前的方法退出,并返回那个值。 点击进入我的博客 4.1 true&false Java的条件语句只能使用布尔值来决定执行路径 4.2 if-else 4.3 循环语句 while、for、do-while do-...

    PingCAP 评论0 收藏0
  • Java编程思想笔记10.内部类

    摘要:但远不止如此,内部类了解外部类,并能与之通信。内部类还拥有其外围类的所有元素的访问权。普通内部类内不能有域和方法。特点普通内部类对象隐式的保存了外部类对象,但嵌套类并非如此。局部内部类可以访问当前代码块内的常量,以及此外围类的成员。 点击进入我的博客 可以把一个类的定义放在另一个类的定义内部,这就是内部类。Java最晦涩的部分之一。内部类看起来就像是一种代码隐藏机制,将类只与其他类的...

    wslongchen 评论0 收藏0

发表评论

0条评论

since1986

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<