7.Java中的字符串
1.String的特性
- 特性一:不可变性
- String s=new String(“yangyun")
- s=s.toUpperCase();
- 这里的s,s占用的空间是不一样的(地址不相同),前提是toUpperCase函数确实改变了原始s的内容。
为什么String是不可变对象?-----cankai
- 1.效率问题
- 如果你知道一个对象是不可变的,那么需要拷贝这个对象的内容时,就不用复制它的本身而只是复制它的地址,复制地址(通常一个指针的大小)需要很小的内存效率也很高。
- 2.安全性
- 不可变对象对于多线程是安全的,因为在多线程同时进行的情况下,一个可变对象的值很可能被其他进程改变,这样会造成不可预期的结果,而使用不可变对象就可以避免这种情况。
- 3.字符串常量池的需要-----后续介绍
String s1= "ab" + "cd";
String s2= "abc" + "d";
s1,s2指向的地方是相同的,hashCode值也相同(可以缓存HashCode的值),如果String可以改变,那么s1改变会影响到s2,会带来安全问题。
- 特性二:重载"+"
- 操作符重载的含义:特定的操作符在特殊的类中有特别的含义;
- “+”,”+=“是Java 中仅有的两个重载运算符;java不允许程序员重载任何的运算符
- 连接的时候如果发现不是String,会尝试调用对象的toString 方法
//Object类的hashCode函数
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
- 特性三:字符串的连接
- 方法一:使用+=对字符串进行连接
- 使用+,+=链接字符串的后果: (会产生一大堆需要垃圾回收的中间对象,从而效率低下)
- JVM优化--自动的使用StringBuilder进行连接--不会产生不被引用的中间对象
- 但是每连接一个String对象,JVM虽然不会创建一个没有办法引用的String对象,但是他会每次都创建一个StringBuilder对象---也是浪费
- 方法二:使用StringBuilder的append函数对字符串进行连接---------推荐
- 只需要创建一个StringBuilder进行连接
- 特性四:"字符串常量"
- 说明:字符串是不可变的,但是字符串引用(指向)是可以改变的,字符串常量是指字符串与常量进行绑定之后,指向就不能发生变化
- 举例:
- final String a=new String("a");//这里的a就不能改变指向
- 特性五:重要的String函数(不熟悉的)
- String.intern()—加入字符串常量池,并返回该字符串
- String.equalsIgnoreCase()—忽略大小写比较
- String.indexof(string1)------是否存在包含string1,存在返回index,不存在返回-1
- string.lastIndexof(string)---从后向前查找
- string.contains(string)------是否存在,返回boolean类型
- string.trim()-----------------删除前后的空白符号
- 2.StringBuilder类学习
- 说明:用于连接字符串,对字符串进行处理
- 构造函数:
- StringBuilder sbuilder=new StringBuilder();//缓冲区16
- StringBuilder sbuilder=new StringBuilder(20);//缓冲区为20
- StringBuilder sbuilder=new StringBuilder(“Hello”);//初始字符Hello
- 功能函数:
- append();//向末尾添加字符串
- reverse();//逆向装置字符串
- insert(index,value);//从index开始处开始插入字符串
- delete(startindex,endindex);//删除index在startindex~endindex-1的字符
- replace(startindex,endindex,String);//使用String代替startindex~endindex之间的字符,长度自行调整,String不够用空格添加,长了就截取
- toString();转为String
- 无意识的递归-对象toString函数的调用
- List<Person> list=new ArrayList(Arrays.asList(new Person(“Yangyun”),new Person(“Tim")));
- System.out.println(list);
- 如果:Person没有toString()对象——会自动调用每一个对象的super.toString()—Object的toString函数
- 调用对象的toString()函数,若对象没有toString函数,调用对象的父类的toString()函数
- 3.字符串pool与heap(重要)
- 阶段一:编译阶段
- 字符串常量放到一个字符串池(pool of literal strings)中,而运行时字符串常量池成为常量池的一部分。
- 这里的字符串常量指的是String string="yangyun",String string="abc"+"def";
- 阶段二:程序员使用intern方法可以改变字符串池的大小。
- 当调用intern()方法时,如果字符串池中已经包含一个等于此String 对象的字符串 (用equals(Object)方法确定),则返回字符串池中的字符串。否则,将此String 对象添加到字符串池中,并返回此String 对象的引用。
- 字符串的比较:
- 1.String.equals(String)--比较字符串的
- 2.==(实际比较的是String对象地址)
- 举例:
- String str1 = "java"; // str1指向字符串池
- String str2 = "blog"; // str2指向字符串池
- String s = str1 + str2;//这条语句会创建多少个对象
- s是指向堆中值为"javablog"的对象,+ 运算符会在堆中建立起来两个String对象,这两个对象分别是"java","blog",也就是说从字符串池中复制这两个值,然后在堆中创建两个对象,然后再建立对象s,然后将"javablog"的堆地址赋给s。 // 这条语句总共创建了多少个对象?(三个吧)
- 如果改成以下两种方式:
- 1.s是常量池中的字符串
- String s = "java" + "blog"; // 直接将"javablog"放入字符串池中
- System.out.println(s == "javablog"); // 结果为true
- 2.s是堆中的字符串
- String s = str1 + "blog"; // 不放入字符串池,而是在堆中分配
- System.out.println(s == "javablog"); // 结果为false
- 总结:
- 三种创建String对象的方式
- String string=“abc”;//pool中有则不创建直接引用,否则创建并加入pool
- final String string=“abc”;//pool中
- String string=new String(“abc”);//heap分配内存创建对象
- String string=“abc”+s1;//s1为new创建—那么string也是使用heap
参考文献:
http://www.codeceo.com/article/why-java-string-class-static.html
7.Java中的字符串的更多相关文章
- [原创]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 & ...
- 为什么Java中的字符串是不可变的?
原文链接:https://www.programcreek.com/2013/04/why-string-is-immutable-in-java/ java字符串是不可变的.不可变类只是一个不能修改 ...
- 详解Java中的字符串
字符串常量池详解 在深入学习字符串类之前, 我们先搞懂JVM是怎样处理新生字符串的. 当你知道字符串的初始化细节后, 再去写String s = "hello"或String s ...
随机推荐
- 【USACO 2.3】Money Systems(dp)
v种货币,求有多少种组成和为n. dp[i][j]表示前i种货币价格为j有多少种方案,dp[i][j]+=dp[i-1][j-c]. http://train.usaco.org/usacoprob2 ...
- win10下JDK的安装与环境变量配置
1.到官网下载最新版本的JDK http://www.oracle.com/technetwork/java/javase/downloads/index.html 2.安装JDK,同安装其他软件一样 ...
- 配置windows 系统PHP系统环境变量
1. 首先到php官网下载php-5.3.6-nts-Win32-VC9-x86.ZIP 解压到电脑硬盘.将文件解压到文件夹php5.3.6下载地址:http://www.php.net/downlo ...
- java高新技术-枚举
1.什么是枚举 枚举是jdk1.5后才增加的新特性 用枚举就是要规定一个新的类型,那么要用这个类型的值就必须是我规定的那些值.如果不是那些值,编译器就会报错,好处是编译时就会做出判断 2.用普通类模拟 ...
- myeclipse给项目改了名字,但部署tomcat的项目名还是原来的
如标题所示: 在myeclipse中按F2改了项目名称,之前在tomcat中部署的名称是另一个,再次重新部署,永远是上一个的旧名称 解决办法: 项目点右键-properties-左上角搜索框输入web ...
- eclipse中SSH三大框架环境搭建<二>
通过上一篇博客我们可以轻松搭建strtus2的环境,接下来由我来继续介绍spring的环境搭建以及spring注入的简单使用 相关链接:eclipse中SSH三大k框架环境搭建<一> ec ...
- php多进程总结
本文部分来自网络参考,部分自己总结,由于一直保存在笔记中,并没有记录参考文章地址,如有侵权请通知删除.最近快被业务整疯了,这个等抽时间还需要好好的整理一番. 多进程--fork 场景:日常任务中, ...
- Twemproxy 缓存代理服务器
Twemproxy 缓存代理服务器 Twemproxy 概述 Twemproxy(又称为nutcracker)是一个轻量级的Redis和Memcached代理,主要用来减少对后端缓存服务器的连接数.T ...
- PHP curl获取页面内容,不直接输出到页面,CURLOPT_RETURNTRANSFER参数设置
使用PHP curl获取页面内容或提交数据,有时候希望返回的内容作为变量储存,而不是直接输出.这个时候就必需设置curl的或true. 1.curl获取页面内容, 直接输出例子: <?php $ ...
- PHP 的异常处理、错误处理:error_reporting,try-catch,trigger_error,set_error_handler,set_exception_handler,register_shutdown_function
一.错误.异常 等级常量表 error:不能在编译期发现的运行期错误,比如试图用 echo 输出一个未赋值的变量,这类问题往往导致程序或逻辑无法继续下去而需要中断: exception:程序执行过程中 ...