前言

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

不可变String

String对象是不可变的

重载"+"与StringBuilder

String对象是不可变的,可以给String对象加任意多得别名。

String对象具有只读特性,所以指向它的任何引用都不可能改变它的值。

String a = "a";
String b = a;
System.out.println("first: a=" + a + " b=" + b);
b = "b";
System.out.println("second: a=" + a + " b=" + b);

运行结果:

first: a=a b=a
second: a=a b=b

String对象的不可变性会带来一定的效率问题。

比如为String对象重载的"+"操作符。

重载:一个操作符在应用于特定类时,被赋予特殊的意义。Java中,用于String的"+"与"+="是仅有的两个重载过的操作符。Java不允许程序员重载任何操作符。

public class Connection {
public static void main(String[] args) {
String str = "hello";
String anotherStr = "abc" + str + "def" + 123;
System.out.println(anotherStr);
}
}
Compiled from "Connection.java"
public class Connection {
public Connection();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return public static void main(java.lang.String[]);
Code:
0: ldc #2 // String hello
2: astore_1
3: new #3 // class java/lang/StringBuilder
6: dup
7: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V
10: ldc #5 // String abc
12: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
15: aload_1
16: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
19: ldc #7 // String def
21: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
24: bipush 123
26: invokevirtual #8 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
29: invokevirtual #9 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
32: astore_2
33: getstatic #10 // Field java/lang/System.out:Ljava/io/PrintStream;
36: aload_2
37: invokevirtual #11 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
40: return
}

无意识的递归

Java中的每个类从根本上都是继承自Object。

public class Object {
...
//Object类的toString方法
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
...
}

标准容器类同样是继承自Object类,因此容器类都有toString()方法,并且覆写了这个方法来表达容器本身和它所包含的对象。

比如ArrayList.toString()方法,查看源代码可知,ArrayList类继承自AbstractList类,而AbstractList类覆写了toString()方法。

它会遍历AbstractList中所包含的所有对象,并调用每个元素上的toString方法。


public abstract class AbstractCollection<E> implements Collection<E> {
...
public String toString() {
Iterator<E> it = iterator();
if (! it.hasNext())
return "[]"; StringBuilder sb = new StringBuilder();
sb.append('[');
for (;;) {
E e = it.next();
sb.append(e == this ? "(this Collection)" : e);
if (! it.hasNext())
return sb.append(']').toString();
sb.append(',').append(' ');
}
}
...
}

想打印对象的内存地址,应该调用super.toString()方法,也就是基类Object的toString()方法。

class A{
public static void main(String [] args){
System.out.println(new A());
}
@Override
public void toString(){
// return "A:"+this;//会造成递归调用,导致栈溢出。
return "A:"+super.toString();
}
}

正则表达式

解决各种字符串处理相关的问题:匹配,选择,编辑以及验证。

基础

以某种方式来描述字符串

Java中,\表示:插入一个正则表达式的反斜线,它后面的字符具有特殊的意义。

数字:\\d
反斜线:\\\\

String类中的,正则匹配方法:

1.匹配matches()方法。查看源代码,可以知道该方法实际上是调用了Pattern类的matches()方法来实现正则表达式的匹配功能的。

2.分隔split()方法,这个方法能将字符串从正则表达式匹配的地方切开。

3.替代replaceAll(),replaceFirst()方法

 ...
public boolean matches(String regex) {
return Pattern.matches(regex, this);
}
public String[] split(String regex, int limit) {
/* fastpath if the regex is a
(1)one-char String and this character is not one of the
RegEx's meta characters ".$|()[{^?*+\\", or
(2)two-char String and the first char is the backslash and
the second is not the ascii digit or ascii letter.
*/
char ch = 0;
if (((regex.value.length == 1 &&
".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1) ||
(regex.length() == 2 &&
regex.charAt(0) == '\\' &&
(((ch = regex.charAt(1))-'0')|('9'-ch)) < 0 &&
((ch-'a')|('z'-ch)) < 0 &&
((ch-'A')|('Z'-ch)) < 0)) &&
(ch < Character.MIN_HIGH_SURROGATE ||
ch > Character.MAX_LOW_SURROGATE))
{
int off = 0;
int next = 0;
boolean limited = limit > 0;
ArrayList<String> list = new ArrayList<>();
while ((next = indexOf(ch, off)) != -1) {
if (!limited || list.size() < limit - 1) {
list.add(substring(off, next));
off = next + 1;
} else { // last one
//assert (list.size() == limit - 1);
list.add(substring(off, value.length));
off = value.length;
break;
}
}
// If no match was found, return this
if (off == 0)
return new String[]{this}; // Add remaining segment
if (!limited || list.size() < limit)
list.add(substring(off, value.length)); // Construct result
int resultSize = list.size();
if (limit == 0) {
while (resultSize > 0 && list.get(resultSize - 1).length() == 0) {
resultSize--;
}
}
String[] result = new String[resultSize];
return list.subList(0, resultSize).toArray(result);
}
return Pattern.compile(regex).split(this, limit);
}
public String replaceFirst(String regex, String replacement) {
return Pattern.compile(regex).matcher(this).replaceFirst(replacement);
}
public String replaceAll(String regex, String replacement) {
return Pattern.compile(regex).matcher(this).replaceAll(replacement);
}
...

创建正则表达式

![http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html]

量词

1.贪婪型

2.占有型

3.勉强型

CharSequence

接口CharSequence从CharBuffer,String,StringBuffer,StringBuilder类之中抽象出字符序列的的一般化定义:

interface CharSequence{
charAt(int i);
length();
subSequence(int start,int end);
toString();
}

Pattern和Matcher

String类功能有限,我们可以自己构造强大的正则表达式对象。

导入java.util.regex包,使用静态方法Pattern.compile()来编译正则表达式。

  public static Pattern compile(String regex) {
return new Pattern(regex, 0);
}

compile()方法返回一个Pattern对象,表示编译后的正则表达式。

  public Matcher matcher(CharSequence input) {
if (!compiled) {
synchronized(this) {
if (!compiled)
compile();
}
}
Matcher m = new Matcher(this, input);
return m;
}

对于已编译正则表达式的Pattern对象的matcher()方法,加上要被匹配的字符串,返回一个Matcher对象。

使用Matcher对象的各种方法,我们就能判断各种不同类型的匹配是否成功。

boolean matches() //判断整个字符串是否匹配
boolean lookingAt()//判断字符串的起始部分是否能够匹配
boolean find()
boolean find(int start)

Java编程思想学习笔记——字符串的更多相关文章

  1. [Java编程思想-学习笔记]第3章 操作符

    3.1  更简单的打印语句 学习编程语言的通许遇到的第一个程序无非打印"Hello, world"了,然而在Java中要写成 System.out.println("He ...

  2. Java编程思想学习笔记——一切都是对象

    前言 Java是基于C++的,但Java是一种更加纯粹的面向对象程序设计语言. C++和Java都是混合/杂合型语言.杂合型语言允许多种编程风格. 用引用操纵对象 每种编程语言都有自己操纵内存中元素的 ...

  3. Java编程思想 学习笔记1

    一.对象导论 1.抽象过程 Alan Kay曾经总结了第一个成功的面向对象语言.同时也是Java所基于的语言之一的Smalltalk的五个基本特性,这些特性表现了纯粹的面向对象程序设计方式 1)万物皆 ...

  4. Java编程思想学习笔记——类型信息

    前言 运行时类型信息(RTTI:Runtime Type Information)使得我们可以在程序运行时发现和使用类型信息. Java在运行时识别对象和类的信息的方式: (1)一种是RTTI,它假定 ...

  5. [Java编程思想-学习笔记]第1章 对象导论

    1.1  抽象过程 Java是一门面向对象的语言,它的一个优点在于只针对待解问题抽象,而不用为具体的计算机结构而烦心,这使得Java有完美的移植性,也即Java的口号"Write Once, ...

  6. Java编程思想 学习笔记12

    十二.通过异常处理错误  Java的基本理念是“结构不佳的代码不能运行”. Java中的异常处理的目的在于通过使用少于目前数量的代码来简化大型.可靠的程序的生成,并且通过这种方式可以使你更加自信:你的 ...

  7. Java编程思想 学习笔记11

    十一.持有对象  通常,程序总是根据运行时才知道的某些条件去创建新对象.在此之前,不会知道所需对象的数量,甚至不知道确切的类型. Java实用库还提供了一套相当完整的容器类来解决这个问题,其中基本的类 ...

  8. Java编程思想 学习笔记5

    五.初始化与清理 1.用构造器确保初始化  在Java中,通过提供构造器,类的设计者可确保每个对象都会得到初始化.创建对象时,如果其类具有构造器,Java就会在用户有能力操作对象之前自动调用相应的构造 ...

  9. Java编程思想 学习笔记10

    十.内部类  可以将一个类的定义放在另一个类的定义内部,这就是内部类. 内部类是一种非常有用的特性,因为它允许你把一些逻辑相关的类组织在一起,并控制位于内部的类的可视性.然而必须要了解,内部类和组合是 ...

随机推荐

  1. Web程序中的懒加载异常说明及解决方案

    所谓懒加载(lazy)就是延时加载,延迟加载. 什么时候用懒加载呢,我只能回答要用懒加载的时候就用懒加载. 至于为什么要用懒加载呢,就是当我们要访问的数据量过大时,明显用缓存不太合适, 因为内存容量有 ...

  2. 【应用笔记】【AN005】Qt开发环境下基于RS485的4-20mA电流采集

    简介 4-20mA电流环具有广泛的应用前景,在许多行业中都发挥着重要作用.本文主要介绍在Qt开发环境下基于RS485实现4-20mA电流采集,实现WINDOWS平台对数据的采集.分析及显示. 系统组成 ...

  3. mysqldump具体应用实例

    1.导出整个数据库  mysqldump -h主机 -u 用户名 -p 数据库名 > 导出的文件名      mysqldump -h127.0.0.1 -u wcnc -p smgp_apps ...

  4. sam9260 闲鱼

    开发板 https://2.taobao.com/item.htm?spm=2007.1000338.6.8.5vXVdv&id=534550318896 核心板 https://item.t ...

  5. CAS (12) —— CAS TicketRegistry使用JPA方案数据源c3p0与JNDI

    CAS (12) -- CAS TicketRegistry使用JPA方案数据源c3p0与JNDI tomcat版本: tomcat-8.0.29 jdk版本: jdk1.8.0_65 cas版本: ...

  6. Matlab——plot polyfit polyval

    p=polyfit(x,y,m) 其中, x, y为已知数据点向量, 分别表示横,纵坐标, m为拟合多项式的次数, 结果返回m次拟合多项式系数, 从高次到低次存放在向量p中. y0=polyval(p ...

  7. [zhuan]《MEF程序设计指南》博文汇总

    http://www.cnblogs.com/beniao/archive/2010/08/11/1797537.html 在MEF之前,人们已经提出了许多依赖注入框架来解决应用的扩展性问题,比如OS ...

  8. 【HBase】zookeeper在HBase中的应用

    转自:http://support.huawei.com/ecommunity/bbs/10242721.html Zookeeper在HBase中的应用 HBase部署相对是一个较大的动作,其依赖于 ...

  9. 自然语言交流系统 phxnet团队 创新实训 个人博客 (九)

    情感倾向可认为是主体对某一客体主观存在的内心喜恶,内在评价的一种倾向.它由两个方面来衡量:一个情感倾向方向,一个是情感倾向度. 情感倾向方向也称为情感极性.在微博中,可以理解为用户对某客体表达自身观点 ...

  10. Windows IOT 开发入门(硬件入门)

    接上文,在准备工作完成之后.接下来应该要熟悉硬件和架构了. 以下是一个简易物联网架构设计图 关于微软云这里就不说太多了.有兴趣的朋友可以去这里了解更多https://www.azure.cn/. 在上 ...