- 浏览: 220209 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
zi_wu_xian:
顶5楼,POI操作word和excel还是太复杂了,并且针对d ...
使用POI操作Excel和Word -
贝塔ZQ:
poi操作word、excel代码好多啊,用插件试试吧,网上不 ...
使用POI操作Excel和Word -
wap816:
@CacheEvict(value = ...
SpringEL详解及应用 -
string2020:
List<Map<String,Map<St ...
开源工具 — Apache Commons Collections -
uniqueX:
mark!
并发编程 — 判断线程安全
前言:由于上一个星期工作繁忙,利用上下班和晚上睡前空余的时间拜读了秦小波老师的《改善Java程序的151建议》,感觉廓然开朗,注意到了很多平时在编写代码中并不会注意的问题,甚至感觉自己对Java只是略懂皮毛,不足以登大雅之堂,特此与读者分享读书笔记,以下内容摘自《改善Java程序的151建议》一书和笔者的理解
Java高质量代码系列文章
面向对象篇:http://ray-yui.iteye.com/blog/1926984
数据类型篇:http://ray-yui.iteye.com/blog/1927251
字符串篇:http://ray-yui.iteye.com/blog/1927647
数组与集合(1):http://ray-yui.iteye.com/blog/1928170
数组与集合(2):http://ray-yui.iteye.com/blog/1930155
枚举与注解:http://ray-yui.iteye.com/blog/1931408
泛型与发射:http://ray-yui.iteye.com/blog/1933127
异常:http://ray-yui.iteye.com/blog/1938946
杂:http://ray-yui.iteye.com/blog/1942591
继上一章讲了数据类型,但在Java当中,什么数据类型使用频率最高,最受大家喜爱?那就是我们无限兼容的String类型,拥有诸多方法的String类型,近乎万能的String类型,而在使用String类型当中我们要注意什么?
1.推荐使用String直接赋值
首先我们来看一道经典的题目
public static void main(String[] args) { String str1 = "Hello"; String str2 = "Hello"; String str3 = new String("Hello"); System.out.println(str1 == str2); // 输出结果为true System.out.println(str1 == str3); // 输出结果为false }
以上代码,相信老鸟并不陌生,或者在学习过程中接触,或者在面试题上坑过,原因是Java当中为了避免系统大量的产生String对象,于是就设计出一个字符串常量池,当创建一个String时,会首先在常量池当中检查是否存在这个Hello这个常量,若然不存在,创建,若然存在,将内存地址指向此常量地址,str1赋值时,首先在常量池中创建了Hello,而str2再赋值时,Java检查到常量池中有Hello,直接将Hello的地址赋予了str2,造成str1==str2的情况,而new String的情况下,Java不会去常量池寻找,而是直接在堆中建立对象,所以使用str1==str3自然不成立,通过上面的介绍,由于常量池是由JVM本身进行维护的,所以JVM本身已对常量池进行了大量优化,所以使用直接赋值的方式会比使用new String的方式效率更高,更节省内存空间.
2.注意正则表达式引发的问题
请观察以下一段代码
public static void main(String[] args) { // 1 String str1 = "AHelloA"; str1 = str1.replaceAll("A", ""); System.out.println(str1.equals("Hello")); // 输出为true // 2 String str2 = "$Hello$"; str2 = str2.replaceAll("$", ""); System.out.println(str2.equals("Hello")); // 输出为false // 3 String str3 = "$Hello$"; str3 = str3.replaceAll("\\$", ""); System.out.println(str3.equals("Hello")); // 输出为true // 4 String str4 = "$Hello$"; // 更改了replace方法 str4 = str4.replace("$", ""); System.out.println(str4.equals("Hello")); // 输出true }
注意观察//2 ,大家还记得正则表达式吗?这是因为replaceAll的方法其实是接受一个正则表达式,而$符号刚好是正则表达式的结束符号,所以出现了//2的情况,以后使用replaceAll时需要注意
3.注意String的不变性
请观察以下代码
public static void main(String[] args) { // 1 String str1 = "Hello"; str1 += " World"; System.out.println(str1); // 输出Hello World // 2 str1.replace("World", ""); System.out.println(str1); // 输出Hello World // 3 str1.substring(3); System.out.println(str1); // 输出Hello World }
在上面的代码当中,//1中,究竟创建了多少个String?一共是创建了3个,第一为Hello,第二为World,第三为Hello World,因为直接赋值的方式是在字符串常量池中生成的常量,什么是常量?不可变就为常量,因为不可变,所以//1中产生的了3个String,而//2中为什么我替换了还是等于Hello World呢?这也是因为不变性,仔细的你会发现,String类中提供的修改字符串的方法,包括substring,replace,concat等都是返回一个新的字符串,这是因为字符串的不变性造成的,所以在调用这些方法时需要用另一个或本调用的string去进行接收,//3同理
4.注意字符串的位置
请观察以下代码
public static void main(String[] args) { String str1 = 1 + 2 + "Hello"; System.out.println(str1); // 输出3Hello String str2 = "Hello" + 1 + 2; System.out.println(str2); // 输出Hello12 }
笔者认为String是一个霸道的类型,而且霸道得我很欢喜,因为任何与String类型进行+号操作的其他类型,都会自动升格为String类型,而上例中是因为首先执行1+2的操作,再偶遇到String的Hello,再进行了自动升格,而第二个例子中,在还没进行整形的加法运算时,就首先偶遇到了String,已经自动提升为String,所以就等于Hello1+2的操作,自然等于Hello12
5.正确使用String,StringBuffer,StringBuilder
在上文当中,曾经提到过String的不变性,在String原因下,就产生出了StringBuffer和StringBuilder,后2者为可变的字符串,亦可以称为缓冲字符串,主要原理其实很简单,就是缓冲字符串中的字符串形式是char数组,以下来分析StringBuffer和String的几点不同
1.在频繁的字符串运算,例如拼接,删除,增加,替换,解释XML,进行SQL拼接
的时候,请优先考虑使用StringBuffer
2.在性能考虑方面,由于StringBuffer带有缓冲区,而且最终使用toString()
方法转换成1个字符串,我们试想,StringBuffer无论里面的信息是多么的
复杂,但最终是生成了1个字符串对象,效率会比用+号拼接不停生成字符串
的效率要高
3.想使用更多功能时,例如字符串翻转reverse,字符串插入insert,这些都是
String所不提供的,而StringBuffer却支持,所以想增加某些功能时,使用
StringBuffer
4.StringBuffer和StringBuilder区别?很简单,StringBuffer是线程安全的,
在多线程的环境底下应该使用StringBuffer,而StringBuilder线程是不
安全的,由于现在流行的SSH框架,而struts2中Action是线程安全的,所以
请大胆的使用StringBuilder
6.推荐在复杂字符串操作中使用正则表达式
正则表达式是笔者非常喜爱的东西,对字符串的操作而言,简直是万能,但却不容易一眼看穿究竟正则想表达些什么,因为毕竟是以符号来表达,在String中很多操方法都支持正则表达式,例如replace,split,substring等等,都知道正则表达式的参数,所以在操作复杂的字符串例如邮箱验证时,请务必使用正则表达式
7.使用字符串解决编码问题
相信各位接触过Web开发经验的开发人员都肯定接触过乱码问题,有时是从Web接受时遇到的,有时是从数据库中读取到乱码,而乱码的元凶就在于我们的IDE,使用javac进行编译时,JDK默认生成的编码是UTF-8的UNICODE编码,但在IDE开发进行编译时,若没有指定的话就会使用机器默认的语言,例如Window就会使用GBK等,而怎么样解决这个问题呢?除了在框架配置中解决,还可以在String当中使用代码来解决乱码,请看以下例子
public static void main(String[] args) throws UnsupportedEncodingException { String str1 = "你好"; // 第一种方法,此种方法需要知道来源字符串的编码 byte[] byte1 = str1.getBytes("GBK"); String str2 = new String(byte1); // 第二种方法,此种方法需要知道转变为什么格式的字符串,推荐使用 String str3 = new String(str1.getBytes(), "UTF-8"); }
8.对字符串排序持宽容心态
例如创建了一个字符串数组,使用Arrays.sort()进行自然排序,注意是自然排序,就会出现排序混乱的情况,为什么呢?因为我们Java对字符串排序时是根据了UNICODE编码来进行排序,是UNICODE编码对汉字的顺序并不是连贯连续的,所以若然要对字符串进行精确排序,可以选择使用pingyin4j转换成拼音后再首字母排序
总结:
笔者在本文章中只从《改善Java程序的151建议》中提取部分进行归纳性叙述,推荐各位读者购买这本书,该书不仅从事例中学习,而且涉及到原理,底层的实现,不仅告诉你应该怎么做,还告诉你为什么要这样做.
评论
2 楼
ray_yui
2013-08-30
chenjingbo 写道
字符串相加的,编译器会自动帮你变成 StringBuilder的.
是的,我记得是在Java6才会,但会不停的调用toString()方法
1 楼
chenjingbo
2013-08-30
字符串相加的,编译器会自动帮你变成 StringBuilder的.
发表评论
-
并发编程 — 实现线程安全
2015-08-12 09:03 2308并发编程系列文章: 初解线程池:http://r ... -
并发编程 — 优化小技巧
2015-08-10 23:54 0并发编程系列文章: 初解线程池:http://r ... -
并发编程 — 判断线程安全
2015-08-05 10:11 5557并发编程系列文章: ... -
并发编程 — volatile
2015-07-30 10:11 2202并发编程系列文章: 初解线程池:http://r ... -
数据库储存不确定实体
2014-07-08 09:52 2294相信在项目开发当中都曾经遇到过,有某些要储蓄到数 ... -
同步操作降低效率解惑
2014-06-30 10:20 3295相信在读者刚接触Java的时候,都曾经学习到线程 ... -
并发编程 — 并发数据结构
2014-06-24 09:58 6640并发编程系列文章: 初解线程池:http://r ... -
并发编程 — 并发数据类型
2014-06-16 10:03 5451并发编程系列文章: 初解线程池:http://r ... -
并发编程 — 详解线程池
2014-06-03 09:51 6014本文章需要对JDK5 Executor框架有所了解,请读者先 ... -
并发编程 — 初解线程池
2014-05-28 09:57 7557并发编程系列文章: 初解线程池:http://r ... -
线程池详解
2014-05-26 18:20 0本文章需要对JDK5 Executor框架有所了 ... -
高级字节码生成工具 — Javassist
2014-03-11 09:57 6426AOP系列文章: Spring AOP:http ... -
实现AOP — CGLIB
2014-03-06 09:50 3977AOP系列文章: Sp ... -
实现AOP — Spring AOP
2014-03-03 10:02 4269AOP系列文章: Spring AOP:http ... -
cglib
2014-01-11 19:11 0什么是CGLIB? CGLIB是一个强大的高性能 ... -
Java高质量代码之 — 杂
2013-09-16 09:53 4747前言:由于上一个星期工作繁忙,利用上下班和晚上睡前空余的时间 ... -
Java高质量代码之 — 异常
2013-09-09 09:35 6744前言:由于上一个星期工作繁忙,利用上下班和晚上睡前空余的时间 ... -
Java高质量代码之 — 泛型与反射
2013-08-29 09:36 18073前言:由于上一个星期工作繁忙,利用上下班和晚上睡前空余的时间 ... -
Java高质量代码之 — 枚举与注解
2013-08-27 09:59 15823前言:由于上一个星期工作繁忙,利用上下班和晚上睡前空余的时间 ... -
Java高质量代码之 — 数组与集合(2)
2013-08-23 17:24 2909前言:由于上一个星期工作繁忙,利用上下班和晚上睡前空余的时间 ...
相关推荐
Java中的字符串处理是编程的基础之一,理解`String`和`StringBuffer`的区别以及如何使用这些类对于开发高质量的Java应用程序至关重要。掌握字符串的构造方法和操作技巧可以帮助开发者编写出更加高效、易于维护的代码...
在Java编程语言中,字符串操作是日常开发中的重要部分,因为字符串处理无处不在,从数据解析到用户界面的交互。`StringUtil` 类是这样一个工具类,它集合了多种常用的字符串处理方法,以提高开发效率并减少代码重复...
### Java处理字符和字符串知识点详解 #### 一、概述 在Java编程中,字符和字符串是最常见的数据类型之一。为了方便高效地处理这些数据类型,Java提供...掌握这些基础知识对于提高编程效率和编写高质量的代码至关重要。
### Java查找字符串知识点详解 #### 一、简介 在Java编程中,经常需要对字符串进行查找操作,尤其是在处理文本分析、数据验证等场景时尤为重要。Java标准库提供了强大的`Pattern`和`Matcher`类来支持正则表达式的...
### Java字符串格式化String.format()详解 #### 一、引言 `String.format()` 方法是JDK 1.5引入的新特性,它提供了一种灵活且强大的方式来格式化字符串。这种方法类似于C语言中的`printf`函数,允许开发者通过指定...
本文将详细介绍如何在Java环境中实现从字符串到日期的转换。 #### 二、核心概念与技术 1. **`java.text.SimpleDateFormat`**: 是一个具体的日期/时间格式化子类。它可以用来将`Date`对象格式化为字符串,也可以...
### Java中的字符串详解 #### 一、字符串简介与创建方式 在Java中,字符串是一个非常...理解这些基本的操作方法对于编写高质量的Java代码至关重要。希望本文能够帮助大家更好地理解和掌握Java中的字符串处理技术。
总之,熟练掌握在整个项目中查询字符串的技巧,能够极大地提高开发效率和代码质量。理解查询字符串的使用场景,以及如何在IDE中进行有效搜索,是每个IT专业人员必备的技能。无论是在日常开发、调试,还是在代码审查...
《编写高质量代码:改善java程序的151个建议》一共12章,第1~3章针对java语法本身提出了51条建议,例如覆写变长方法时应该注意哪些事项、final修饰的常量不要在运行期修改、匿名类的构造函数特殊在什么地方等;...
Java 7扩展了switch语句,使其可以直接对字符串进行操作,增强了代码的可读性和灵活性。 3. 字符串连接优化: 在Java 7中,字符串连接操作得到了显著优化。通过内部的StringBuilder或StringBuffer实例,系统能够更...
《编写高质量代码:改善java程序的151个建议》内容简介:在通往“java技术殿堂”的路上,本书将为你指点迷津!内容全部由java编码的最佳实践组成,从语法、程序设计和架构、工具和框架、编码风格和编程思想等五大...
1. **Gson库**:Google开发的Gson库是Java中非常流行的一个JSON库,它能够将Java对象转化为JSON字符串,同时也能够将JSON字符串反序列化为Java对象。例如,我们可以通过`Gson().toJson()`方法将一个Java对象转化为...
在Java开发中,数据交换和存储经常涉及到对象与JSON字符串之间的转换。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。Java提供了多种库来实现对象与...
而在像Java或Python这样的高级语言中,字符串是不可变对象,每次修改都会创建新的字符串实例。这种设计有其优点,例如提高了字符串操作的安全性,但也可能导致性能问题,因为频繁创建新对象会消耗更多的内存。 字符...
### Java 判断字符串是否为空的三种方法 在Java编程中,经常需要判断字符串是否为空(null 或者空字符串)。为了确保程序的健壮性和避免NullPointerException等异常,掌握正确的字符串判断方法至关重要。本文将详细...
Java字符串在编程中扮演着重要角色,它们是不可变的对象,这意味着一旦创建,就不能更改其内容。本资料主要涵盖了字符串的比较、转化以及操作...同时,理解并熟悉Java的关键字和语法细节也是编写高质量代码的基础。
在编程领域,尤其是在使用C++、Java或C#等面向对象的语言时,经常需要将字符串数组转换为单一的string类型。这种操作在处理数据...在实际应用中,根据场景选择合适的方法,并注意性能优化,是实现高质量代码的关键。
本项目“java_code.rar”聚焦于Java实现的字符串加密解密技术,旨在提供一个实用的解决方案来保护敏感信息。 首先,我们需要理解加密和解密的基本概念。加密是将明文(可读信息)转化为密文(不可读信息)的过程,...
在实际应用中,SQL字符串的格式化不仅关乎美观,更是直接影响到代码的可读性和维护性。尤其是在大型项目中,一致的代码风格对于团队协作至关重要。因此,理解并掌握如何使用这样的工具,是每个IT专业人员提升专业...
Java编程规范是一些编程规则和约定,用于编写高质量的Java代码。例如,在上述代码中,使用了camel case命名规则,变量名使用小驼峰命名法。 本文提供了一个使用Java语言统计一个字符串中各个字符出现次数的实例,...