[Java 基础]字符串
String类
实例化String对象
如下代码中,各种初始化方式的效果是一样的,初始化后,String 对象的内容为 "hello" 。
public static void main(String[] args) { // 直接赋值 String str1 = "hello"; // 构造函数方式,参数为 String String str2 = new String("hello"); // 构造函数方式,参数为 StringBuilder String str3 = new String(new StringBuilder("hello")); // 构造函数方式,参数为 StringBuffer String str4 = new String(new StringBuffer("hello")); // 构造函数方式,参数为 char 数组 char[] cz = {'h', 'e', 'l', 'l', 'o'}; String str5 = new String(cz); // 构造函数方式,参数为 byte 数组 byte[] bz = {'h', 'e', 'l', 'l', 'o'}; String str6 = new String(bz); // 先使用默认构造函数,再赋值 String str7 = new String(); str7 = "hello"; }
以上方式可归纳为两类:
(1) 赋值方式
(2) 构造函数方式
传入的参数可以是String、StringBuilder、StringBuffer、char 数组、byte 数组等等。
两种实例化方式比较
一个字符串就是一个 String 类的匿名对象。
匿名对象
对于这样的代码:
String name = "Jack"; // 赋值方式初始化 String 对象
实际上就是在堆中开辟一个内存空间,这个空间的中存储的值为 "Jack"。然后这个空间被 name 变量所引用。
注:在JAVA中,如果一个字符串已经被一个名称所引用,则以后再有相同的字符串声明时,不会重新开辟空间,而是复用之前的空间。这样减少了不必要的空间开销。
例
String str1 = "hello"; String str2 = "hello"; String str3 = "hello";
以上三个String类变量本身是存放在栈内存中,但是它们指向同一块堆内存空间。
而如果使用构造函数方式初始化String类对象,和所有普通类一样,只要new一次,就会新开辟一块堆空间。
综上所述,可以看出赋值方式要优于构造函数方式。
String的内容比较
1、使用 "=="
public static void main(String[] args) { String str1 = "hello"; String str2 = new String("hello"); String str3 = str2; System.out.println("str1 == str2 --> " + (str1 == str2)); System.out.println("str1 == str3 --> " + (str1 == str3)); System.out.println("str2 == str3 --> " + (str2 == str3)); }
运行结果
str1 == str2 --> false str1 == str3 --> false str2 == str3 --> true
从以上代码可以看出,虽然三个字符串内容完全一致,但是使用 "==" 去比较却发现并不完全相等。
这是因为每个String对象的内容实际上是保存在堆内存中的。所以,即使堆中的内容一致,并不代表它们的地址空间也一致。
2、使用equals方法
如果要比较两个字符串的内容是否相等,可以使用 equals 方法。
public static void main(String[] args) { String str1 = "hello"; String str2 = new String("hello"); String str3 = str2; System.out.println("str1 == str2 --> " + (str1.equals(str2))); System.out.println("str1 == str3 --> " + (str1.equals(str3))); System.out.println("str2 == str3 --> " + (str2.equals(str3))); }
运行结果
str1 == str2 --> true str1 == str3 --> true str2 == str3 --> true
String对象不可变
//: StringDemo03.java public class StringDemo03 { public static String upcase(String s) { return s.toUpperCase(); } public static void main(String[] args) { String a = "hello"; System.out.println(a); // hello String b = upcase(a); System.out.println(b); // HELLO System.out.println(a); // hello } } /* Output: hello HELLO hello *///:~
当把a传给 upcase() 方法时,实际传递的是引用的一个拷贝。其实,每当把 String 对象作为方法的参数时,都会复制一份引用,而该引用所指的对象其实一直待在单一的物理位置上,从未动过。
所以指向 String 的任何引用都不可能改变它的值。
不可变性会带来一定的效率问题。例如String类的重载操作符 "+"。
注:JAVA不同于C++,并不允许程序员自定义任何重载操作符。用于String的 "+" 和 "+=" 是JAVA中仅有的两个重载操作符。
操作符"+"可以用来拼接String。方式如下:
String s = "How " + "are " + "you?"; System.out.println(s); /* Output: How are you? *///:~
这种方式的问题在于,会产生一大堆需要垃圾回收的中间对象。
那么,如何避免这种问题呢?
JAVA中提供了两个类:StringBuilder 和 StringBuffer ,它们都有 append() 方法,效率高于 String 的 "+"。
这两个类的差别在于 StringBuffer 是线程安全的,因此开销也更大一些。
String类的常用方法
以下代码是String类的一些常用方法。
public class StringDemo { public static void main(String[] args) { // 获取字符串字符个数 System.out.println(" Goodbye ".length()); // 获取 String 中该索引位置上的 char System.out.println("Computer".charAt(4)); // 复制 byte 到一个目标数组 byte bytes[] = "Winter".getBytes(); // 将字符串转为 byte 数组 System.out.println(new String(bytes)); // 将完整 byte 数组转为字符串 System.out.println(new String(bytes, 1, 3)); // 将部分 byte 数组转为字符串 // 复制 char 到一个目标数组 char chars[] = new char[10]; "Summer".getChars(0, 6, chars, 2); // 将字符串0~6位置的内容拷贝到 char 数组中,从数组位置2开始 System.out.println(new String(chars)); // 将完整 char 数组转为字符串 System.out.println(new String(chars, 1, 3)); // 将部分 char 数组转为字符串 // 字符串转char数组 char[] data1 = "Baby".toCharArray(); for (char c : data1) { System.out.print(c + " "); } System.out.println(); // 如果String不包含此参数,返回-1,否则返回此参数在String中的起始索引。lastIndexOf是从后向前查找 System.out.println("How are you".indexOf("o")); // 查找返回位置 System.out.println("How are you".indexOf("o", 5)); // 查找返回位置, 从位置5开始 System.out.println("How are you".indexOf("z")); // 没有查到返回-1 System.out.println("How are you".lastIndexOf("o")); // 查找返回位置 System.out.println("How are you".lastIndexOf("o", 5)); // 查找返回位置, 从位置5开始 System.out.println("How are you".lastIndexOf("z")); // 没有查到返回-1 // 根据参数截取字符串 System.out.println("Hello World".substring(6)); // 从位置6开始截取 System.out.println("Hello World".substring(0, 5)); // 截取0~5个位置的内容 // 按照指定字符拆分字符串 String[] s = "sample@sina.com".split("@"); for (int i = 0; i < s.length; i++) { System.out.println(s[i]); } // 去除左右空格 System.out.println(" Night ".trim()); // 去除左右空格输出 // 转换大小写 System.out.println("China".toLowerCase()); System.out.println("China".toUpperCase()); // 判断是否以指定的字符串开头或结尾 if ("**NAME".startsWith("**")) { System.out.println("**NAME 以**开头"); } if ("NAME**".endsWith("**")) { System.out.println("NAME** 以**结尾"); } // 替换源子字符串为目标子字符串 System.out.println("good".replaceAll("o", "x")); } }
StringBuilder类
String类是不可改变的,所以你一旦创建了String对象,那它的值就无法改变了。 如果需要对字符串做很多修改,那么应该选择使用StringBuffer & StringBuilder 类。
StringBuilder 类的用法大部分与 String 类相似。
示例代码如下:
StringBuilder str = new StringBuilder(); str.append("How ").append("are ").append("you?"); System.out.println(str); /* Output: How are you? *///:~
StringBuffer类
StringBuffer 类和 StringBuilder 类大致相同。
但是 StringBuffer 是线程安全的,因此开销也更大一些。
参考资料
JAVA 编程思想
JAVA 开发实战经典
[Java 基础]字符串的更多相关文章
- Java基础-字符串(String)常用方法
Java基础-字符串(String)常用方法 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.java的API概念 Java的API(API:Application(应用) Pr ...
- Java基础-字符串连接运算符String link operator
Java基础-字符串连接运算符String link operator 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 字符串链接运算符是通过“+”进行拼接的. 一.使用“+”进行字 ...
- java基础 字符串 “==” 和 “equals” 比较
demo: public class TestStringEquals { public static void main(String[] args) { String a = "test ...
- [Java基础]字符串
1.字符串特点 字符串是常量,创建之后不能修改: 字符串的内容一旦修改,就会马上创建一个新的对象: 字符串实际为一个char value[]={'a','a'};数组: 2.==与equal判断字符串 ...
- java基础---字符串string
1.字符创的概念 java字符串就是Unicode字符序列.例如,串“Java\u2122”由5个Unicode字符J.a.v.a和TM.java没有内置的字符串类型,而是在标准库Java类库中提供了 ...
- Java基础——字符串构建器
StringBuilder类: 可以将许多小段的字符串构建一个字符串. StringBuilder builder = new StringBuilder(); //构造一个空的字符串构建器 buil ...
- Java基础——字符串String
String类 1. String类位于java.lang包中,使用时无需导包. 2. 创建字符串的两种方式: ① 直接指定(字面量声明):String str = "abc"; ...
- Java基础 -- 字符串(格式化输出、正则表达式)
一 字符串 1.不可变String String对象是不可变的,查看JDK文档你就会发现,String类中每一个看起来会修改String值的方法,实际上都是创建一个全新的String对象,以包含修改后 ...
- Java基础 - 字符串 String
字符串就是用字符拼接成的文本值,字符串在存储上类似数组,在java语言中把字符串当做对象进行处理 创建字符串 package com.mingri.chapter_02; public class d ...
随机推荐
- php+redis window
http://download.csdn.net/detail/qwfy326/6572443 wampserver2.2e-php5.3.13-httpd2.2.22-mysql5.5.24-x64
- Android 事件拦截机制一种粗鄙的解释
对于Android事件拦截机制,相信对于大多数Android初学者是一个抓耳挠腮难于理解的问题.其实理解这个问题并不困难. 首先,你的明白事件拦截机制到底是怎么一回事?这里说的事件拦截机制,指的是对触 ...
- Jexus 5.8.2 Beta1发布:为Asp.Net Core进入生产环境提供平台支持
Jeuxs 5.8.2beta1于7月10日正式发布. 有如下更新: 1,为FastCGI提供KEEP_CONN支持,优化FastCGI工作线程池调度算法: 2,完善反向代理的负载均衡策略,支持“随机 ...
- 深入理解CSS弹性盒模型flex
× 目录 [1]版本更迭 [2]display [3]基本概念[4]伸缩容器[5]伸缩项目 前面的话 CSS3引入了一种新的布局模型——flex布局.flex是flexible box的缩写,一般称之 ...
- java 多线程(daemon)
package com.example; public class App { public static void main(String[] args) { DoDaemon d1 = new D ...
- 技术渣如狗,面试虐成猴——本科楼主UC笔试加处女一面全纪录
背景——楼主为广州某校小本一枚,学习成绩渣(班里排名几乎倒数),技术基础渣(算是会敲代码,但很多计算机网络.操作系统的知识都只有模糊的印象).在舍友的鼓励下,收到广州UC的面试通知后,勇敢来到公司直面 ...
- <HTML5和CSS3响应式WEB设计指南>译者序
"不是我不明白,这世界变化快."崔健的这首歌使用在互联网领域最合适不过.只短短数年的功夫,互联网的浪潮还没过去,移动互联网的时代已经来临.人们已经习惯将越来越多的时间花在各种移动设 ...
- [_CN] Eclipse精要与高级开发技术 note
一 eclipse是基于java的 ide ,但根据其体系结构,开发插件,也可拓展到其他语言———————— 尽管如此,但还是很少听说用eclipse来写php或者c的 跨os 三个项目:eclips ...
- MVVM架构~knockoutjs系列之Mapping插件为对象添加ko属性
返回目录 对于一个JS对象来说,如果希望将所有属性进行监视,在之前我们需要一个个对属性添加ko.observable方法,而有了Mapping插件后,它可以帮助我们这件事. 在Mapping出现之前 ...
- 一条Select语句丛生到死的处理过程
以一条普通的“select * from table order by …”语句为例.图2-21中显示为该语句在数据库中各个组件之间的处理过程,各个步骤分别代表: (1)select语句通过网络传送给 ...