JAVA中的字符串小结
String字符串是只读的,不可变的
查看String类的源码,可以发现String类是被final关键字修饰的;
另外还可以看下String类源码中的其它方法实现,随便举个可以修改String值的方法,如字符串拼接方法concat(String str),返回的是一个全新的String对象,而不是在原有的String对象上做修改,代码如下:
public String concat(String str) {
int otherLen = str.length();
if (otherLen == 0) {
return this;
}
int len = value.length;
char buf[] = Arrays.copyOf(value, len + otherLen);
str.getChars(buf, len);
return new String(buf, true);
}
以上代码中,将原有的字符数组和新字符串数组拷贝到一个新的字符数组中,然后new出一个新的String对象返回;
重载“+”与StringBuilder
先看一段使用“+”拼接字符串的代码如下:
package strings;
public class Test {
public static void main(String[] args) {
String a = "test";
String b = a; //b保存了a的引用
//这里编译器会为我们自动创建StringBuilder对象,并调用append方法,
//最终调用StringBuilder的toString方法返回一个新的字符串对象
a = a + "1" + "2" + "3"; //生成了一个新的String对象赋给a
System.out.println(b==a); //引用a指向了新的字符串对象,不相等
System.out.println(a);
}
}
在使用“+”拼接字符串的时候,编译器会为我们自动创建StringBuilder对象,并调用append方法拼接字符串,最终调用StringBuilder的toString方法返回一个新的字符串对象;
或许你认为既然编译器会为我们创建自动StringBuilder对象就可以任意使用“+”操作符了,实际上编译器在某些情况下为我们优化的程度还是不够,如下代码例子,在循环体内使用“+”操作符;
package strings;
public class Test {
public static void main(String[] args) {
String a = "";
for(int i = 0; i < 5; i++){
//编译器每次都会生成一个StringBuilder对象,并调用toString方法生成一个新的String对象
//这中间产生了两个临时对象
a +=i;
}
System.out.println(a);
}
}
可以使用eclipse调试进入源码,会发现,编译器每次都会生成一个StringBuilder对象,并调用toString方法生成一个新的String对象,也就是说。每循环体执行一次,就产生了两个临时对象,可见,当循环次数大的时候,会产生一大堆需要垃圾回收的中间对象,而直接使用StringBuilder就没有这种情况,如下代码,为一个正确的例子:
package strings;
public class Test {
public static void main(String[] args) {
StringBuilder a = new StringBuilder("");
for(int i = 0; i < 5; i++){
a.append(i);
}
System.out.println(a);
}
}
总之,只要涉及字符串的操作,选择StringBuilder总是没错的;
无意识的递归调用
在重写toString方法的时候,如果不注意使用了this关键字,很有可能会调入递归调用的陷阱,如下代码:
package strings;
public class Test {
@Override
public String toString() {
return "addr:" + this;
}
public static void main(String[] args) {
Test t = new Test();
System.out.println(t);
}
}
执行的时候,将抛出StackOverflowError异常,因为toString方法里的"addr:" + this语句会调用自身toString方法,导致无穷无尽的递归调用,然后堆栈溢出,抛出异常;
如果你仅仅是想打印下对象的地址,那么可以调用super.toString()方法,因为Object对象的toString方法默认会调用hashCode打印对象地址;
Sting类的方法
关于String类中的方法,可以查看String源码或JDK的API文档,相对来说还是很好理解的,所谓String对象,实质上来说就是一个字符数组;
String类中的方法,大部分都是操作String内部维护的char value[]数组实现的;
主要方法如下,图片参考自java编程思想-4:

字符串格式化输出
关于格式化输出,了解以下几个例子吧:
format方法:可用于PrintString和PritWriter, 如System.out.format, 如果有C语言的printf语法的使用经验的话,学习format语法会非常轻松,基本类似,如下为一个简单例子:
System.out.format("%5d: %2f", 101,1.131452);
Formatter类:printf 风格的格式字符串的解释程序,如下例子:
package strings;
import java.util.Formatter;
public class Test {
public static void main(String[] args) {
Formatter formatter = new Formatter(System.out);
formatter.format("%5d: %2f", 101, 1.131452);
formatter.close();
}
}
String.format方法:String类的静态方法,在其内部实际上也是通过创建Formatter对象实现的;
System.out.println(String.format("%5d: %2f", 101, 1.131452));
正则表达式
关于正则表达式的具体语法就不细说了,在String类中,涉及正则表达式的主要是以下方法:
matches:判断是否匹配指定的正则表达式规则
split:分割字符串
replaceAll/replaceFirst:将匹配的字符替换为指定的字符串
如下代码为一个简单的使用例子:
package strings;
public class RegexTest {
public static void main(String[] args) {
//匹配数字
System.out.println("1314".matches("\\d+"));
//按数字分割
String[] splitArr = "asdashh45hiu9jkjaks54d".split("-?\\d+");
for(String str:splitArr){
System.out.print(str + ", ");
}
//替换数字为*号
System.out.println();
System.out.println("asdashh45hiu9jkjaks54d".replaceAll("-?\\d+", "*"));
}
}
//输出
//true
//asdashh, hiu, jkjaks, d,
//asdashh*hiu*jkjaks*d
JAVA中的字符串小结的更多相关文章
- Java中的字符串操作(比较String,StringBuiler和StringBuffer)
一.前言 刚开始学习Java时,作为只会C语言的小白,就为其中的字符串操作而感到震撼.相比之下,C语言在字节数组中保存一个结尾的\0去表示字符串,想实现字符串拼接,还需要调用strcpy库函数或者自己 ...
- [原创]Java中的字符串比较,按照使用习惯进行比较
java中的字符串比较一般可以采用compareTo函数,如果a.compareTo(b)返回的是小于0的数,那么说明a的unicode编码值小于b的unicode编码值. 但是很多情况下,我们开发一 ...
- 理解Java中的字符串类型
1.Java内置对字符串的支持: 所谓的内置支持,即不用像C语言通过char指针实现字符串类型,并且Java的字符串编码是符合Unicode编码标准,这也意味着不用像C++那样通过使用string和w ...
- Java中的字符串驻留
转自:http://www.cdtarena.com/javapx/201307/9088.html 最近在工作的时候,一句再正常不过的代码String a = “hello” + “world”;被 ...
- Java中的字符串拼接
Java中的字符串拼接 1.设计源码 /** * @Title:IndexOf.java * @Package:com.you.freemarker.model * @Description: * @ ...
- java中,字符串类型的时间数据怎样转换成date类型。
将字符串类型的时间转换成date类型可以使用SimpleDateFormat来转换,具体方法如下:1.定义一个字符串类型的时间:2.创建一个SimpleDateFormat对象并设置格式:3.最后使用 ...
- Android学习笔记----Java中的字符串比较
用习惯了C#.C++,在做字符串比较时想当然地使用如下语句: string str1 = "abcd", str2 = "abcd"; if(str1==str ...
- 转载:Java中的字符串常量池详细介绍
引用自:http://blog.csdn.net/langhong8/article/details/50938041 这篇文章主要介绍了Java中的字符串常量池详细介绍,JVM为了减少字符串对象的重 ...
- 《Java入门第三季》第二章 认识 Java 中的字符串
什么是 Java 中的字符串.1.在Java的世界里,字符串被作为String类型的对象处理. 2.通用的初始化的方式:String s = new String("i love you & ...
随机推荐
- Kosaraju算法---强联通分量
1.基础知识 所需结构:原图.反向图(若在原图中存在vi到vj有向边,在反向图中就变为vj到vi的有向边).标记数组(标记是否遍历过).一个栈(或记录顶点离开时间的数组). 算法描叙: :对 ...
- ASP.NET MVC 网站开发总结(一)
历经一个多月的努力,工作室的门户网站(http://www.wingstudio.org)终于结束了内部公测. 仔细算一下,大概把网站开发出1.0版本大概用了一个月的时间(主要是利用课余时间),其后大 ...
- WCF学习笔记1--发布使用配置文件的服务
关于WCF的入门网上资料很多,可以参考蒋金楠老师的博客http://www.cnblogs.com/artech/archive/2007/02/26/656901.html,我是从这篇博客开始学习的 ...
- mysql对表操作的各种语句
创建表 create table tb_user( id int(类型)primary key(设置为主键) auto_increment (设置id自增长), 每一个字段用逗号隔开, name va ...
- 百度Java研发面经100题 总结
1. 单例模式常见的应用场景分析. 在23种设计模式中,单例模式排行老大.虽然理解简单,但是对于应用场景.你真正的熟悉么?使用单例,是由于没必要每个请求都新建一个对象,这样既浪费CPU又浪费内存:之所 ...
- [moka同学笔记]window下.htacess文件 与linux下.htacess文件
windows下 # Turn on URL rewritingRewriteEngine On# Installation directoryRewriteBase /# Protect hidde ...
- InfluxDB学习之InfluxDB的安装和简介
最近用到了 InfluxDB,在此记录下学习过程,同时也希望能够帮助到其他学习的同学. 本文主要介绍InfluxDB的功能特点以及influxDB的安装过程.更多InfluxDB详细教程请看:Infl ...
- 【java学习系列】 Android第一本书《第一行代码》
开始Java的学习,从Android,开始吧.<第一代码>开始阅读和调试demo例子. 下面是 <第一行代码>的思维导图:
- Python WMI获取Windows系统信息 监控系统
#!/usr/bin/env python # -*- coding: utf-8 -*- #http://www.cnblogs.com/liu-ke/ import wmi import os i ...
- Monkey测试1——Monkey的使用
Monkey工具使用 一. 什么是Monkey Monkey是Android中的一个命令行工具,可以运行在模拟器里或实际设备中.它向系统发送伪随机的用户事件流(如按键输入.触摸屏输入.手势输入等),实 ...