- 浏览: 793477 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (651)
- Java (39)
- Java 初学者小问题 (66)
- 设计模式 (7)
- 项目管理 (3)
- 数据库 (1)
- 算法 (2)
- Java practices (6)
- Effective Java2读书笔记 (78)
- Linux (2)
- programming ruby 读书笔记 (5)
- Core Java Ninth Edition Volume I 读书笔记 (15)
- Pro Git 读书笔记 (12)
- Git (3)
- Maven in Action 读书笔记 (20)
- Web (12)
- 非技术类书籍 (11)
- 电影 (40)
- Web Cache (1)
- jquery (0)
- 历史 (4)
- Dive Into HTML5 读书笔记 (13)
- 三国演义小学毕业考 (79)
- 高效能人士的7个习惯 读书笔记 (12)
- Java Performance 读书笔记 (3)
- Protocol Buffer 学习笔记 (6)
- Mongo DB 学习笔记 (7)
- Morphia 学习笔记 (7)
- Algorithms -- Princeton 学习笔记 (13)
- String研究 (10)
- Hadoop: The Definitive Guide 读书笔记 (3)
- Java与模式读书笔记 (5)
- Date研究 (3)
- The Roman Empire 听课笔记 (4)
- Algorithms -- Standford 学习笔记 (16)
- Core Java Ninth Edition Volume II 读书笔记 (9)
- Thinking in Java 4th Edition 读书笔记 (21)
- Node : Up and Running 学习笔记 (5)
- Eloquent Javascript (8)
- Smashing Node.js 读书笔记 (1)
- Algorithms II -- Standford 学习笔记 (19)
- Algorithm II -- Princeton 学习笔记 (14)
- 网络安全 (2)
- Javascript (4)
- 正则表达式 (1)
- JAVA 7/8 (15)
- JVM (10)
- NodeJS (1)
- 鸟哥的linux私房菜读书笔记 (14)
- Web Service (1)
- The art of programming (9)
- Introduction to Algorithm 读书笔记 (4)
- Java 源码阅读 (0)
- Spring in Action 读书笔记 (2)
- Java Network Programming 读书笔记 (2)
最新评论
-
心存高远:
谢谢作者分享,刚好看到这里不太明白,现在茅塞顿开。不过runt ...
关于 Maven的传递依赖的理解 -
sxlkk:
851228082 写道甚至在某次技术会议现场遇到《Maven ...
关于 Maven的传递依赖的理解 -
851228082:
851228082 写道a----compile----b-- ...
第五章 坐标和依赖 -
851228082:
a----compile----b-----provided- ...
第五章 坐标和依赖 -
851228082:
甚至在某次技术会议现场遇到《Maven in action》的 ...
关于 Maven的传递依赖的理解
1. CharSequence接口定义了一个只读的char序列。String 实现 CharSequence , Serializable , Comaprable<String>
2. 由 char[] value, int offset, int count 和 int hash组成。
3. 构造函数 public String(String original) 基本上来说是没用的,因为String本身是immutable的,没必要copy一下。但有一个用处:节省空间。比如说,你用subString生成的一个String,它是重用原来的char[]的,而原来的那个String你已经不想用了(这个条件很重要), 你可以用这个构造函数重建一个String来释放空间。
public String(String original) { int size = original.count; char[] originalValue = original.value; char[] v; if (originalValue.length > size) { // The array representing the String is bigger than the new // String itself. Perhaps this constructor is being called // in order to trim the baggage, so make a copy of the array. int off = original.offset; v = Arrays.copyOfRange(originalValue, off, off+size); } else { // The array representing the String is the same // size as the String, so no point in making a copy. v = originalValue; } this.offset = 0; this.count = size; this.value = v; }
4. 提供了一组构造函数,按照给定的Charset来将一个byte 数组 decode成一个字符串。
5. 接收StringBuilder或StringBuffer的构造函数,会将StringBuilder或StringBuffer先toString() 然后将新生成的String中的value , offset 和count赋值给当前String,这时会将char array拷贝一份,所以之后StringBuilder或StringBuffer的修改不会影响到生成的String。但问题是这样不就多生成了一个String对象么?
6. length()返回的是count的值,也就是说是Code Unit的个数,而不是Code Point的个数, 对于Supplementary Character这个length()不是字符个数。如果想得到Code Point的个数可以使用codePointCount方法。
7. getBytes方法,当不传Charset时就用系统默认的Charset将字符串转成相应的编码。
8. public boolean contentEquals(StringBuffer sb) 对 sb作了同步,防止sb中途被修改:
public boolean contentEquals(StringBuffer sb) { synchronized(sb) { return contentEquals((CharSequence)sb); } }
9. public boolean contentEquals(CharSequence cs) 对StringBuilder和StringBuffer做了特殊处理,这样就避免在调用StringBuilder或StringBUffer的charAt方法时做的边界检查了:
public boolean contentEquals(CharSequence cs) { if (count != cs.length()) return false; // Argument is a StringBuffer, StringBuilder if (cs instanceof AbstractStringBuilder) { char v1[] = value; char v2[] = ((AbstractStringBuilder)cs).getValue(); int i = offset; int j = 0; int n = count; while (n-- != 0) { if (v1[i++] != v2[j++]) return false; } return true; } // Argument is a String if (cs.equals(this)) return true; // Argument is a generic CharSequence char v1[] = value; int i = offset; int j = 0; int n = count; while (n-- != 0) { if (v1[i++] != cs.charAt(j++)) return false; } return true; }
10. 当作Case Insensitve比较时代价有点高:
public boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len) { char ta[] = value; int to = offset + toffset; char pa[] = other.value; int po = other.offset + ooffset; // Note: toffset, ooffset, or len might be near -1>>>1. if ((ooffset < 0) || (toffset < 0) || (toffset > (long)count - len) || (ooffset > (long)other.count - len)) { return false; } while (len-- > 0) { char c1 = ta[to++]; char c2 = pa[po++]; if (c1 == c2) { continue; } if (ignoreCase) { // If characters don't match but case may be ignored, // try converting both characters to uppercase. // If the results match, then the comparison scan should // continue. char u1 = Character.toUpperCase(c1); char u2 = Character.toUpperCase(c2); if (u1 == u2) { continue; } // Unfortunately, conversion to uppercase does not work properly // for the Georgian alphabet, which has strange rules about case // conversion. So we need to make one last check before // exiting. if (Character.toLowerCase(u1) == Character.toLowerCase(u2)) { continue; } } return false; } return true; }
11. hashCode的计算:
public int hashCode() { int h = hash; if (h == 0 && count > 0) { int off = offset; char val[] = value; int len = count; for (int i = 0; i < len; i++) { h = 31*h + val[off++]; } hash = h; } return h; }
12. String, StringBuilder和StringBuffer 共享了一段indexOf的逻辑:
static int indexOf(char[] source, int sourceOffset, int sourceCount, char[] target, int targetOffset, int targetCount, int fromIndex) { if (fromIndex >= sourceCount) { return (targetCount == 0 ? sourceCount : -1); } if (fromIndex < 0) { fromIndex = 0; } if (targetCount == 0) { return fromIndex; } char first = target[targetOffset]; int max = sourceOffset + (sourceCount - targetCount); for (int i = sourceOffset + fromIndex; i <= max; i++) { /* Look for first character. */ if (source[i] != first) { while (++i <= max && source[i] != first); } /* Found first character, now look at the rest of v2 */ if (i <= max) { int j = i + 1; int end = j + targetCount - 1; for (int k = targetOffset + 1; j < end && source[j] == target[k]; j++, k++); if (j == end) { /* Found whole string. */ return i - sourceOffset; } } } return -1; }
由此可见,想让indexOf(String substr, int fromIndex) 返回String.length()的唯一方法是, fromIndex >= String.length(),并且子串为空串。
13. lastIndexOf写得有点奇怪:
static int lastIndexOf(char[] source, int sourceOffset, int sourceCount, char[] target, int targetOffset, int targetCount, int fromIndex) { /* * Check arguments; return immediately where possible. For * consistency, don't check for null str. */ int rightIndex = sourceCount - targetCount; if (fromIndex < 0) { return -1; } if (fromIndex > rightIndex) { fromIndex = rightIndex; } /* Empty string always matches. */ if (targetCount == 0) { return fromIndex; } int strLastIndex = targetOffset + targetCount - 1; char strLastChar = target[strLastIndex]; int min = sourceOffset + targetCount - 1; int i = min + fromIndex; startSearchForLastChar: while (true) { while (i >= min && source[i] != strLastChar) { i--; } if (i < min) { return -1; } int j = i - 1; int start = j - (targetCount - 1); int k = strLastIndex - 1; while (j > start) { if (source[j--] != target[k--]) { i--; continue startSearchForLastChar; } } return start - sourceOffset + 1; } }
不是很理解为什么一定要从最后一个字符开始比较,虽然是last index,但匹配字符串没必要从最后一个字符开始比较,而且还用了一个让人不是很舒服的label。我也试着写了一个,才发现,其实要写得逻辑很严密还是需要费一番周折的:
private static int myLastIndexOf(char[] source, int sourceOffset, int sourceCount, char[] target, int targetOffset, int targetCount, int fromIndex) { if (fromIndex < 0) { return -1; } int rightIndex = sourceCount - targetCount; if (fromIndex > rightIndex) { fromIndex = rightIndex; } if (targetCount == 0) { return fromIndex; } char firstChar = target[targetOffset]; int max = targetOffset + targetCount; for (int i = sourceOffset + fromIndex; i >= sourceOffset; i--) { if (source[i] != firstChar) { while (--i >= sourceOffset && source[i] != firstChar) ; } if (i >= sourceOffset) { int j = targetOffset + 1; for (int k = i + 1; j < max && source[k] == target[j]; k++, j++) ; if (j == max) { return i - sourceOffset; } } } return -1; }
14. subString重用了原来的char[]。
15. public String replace(CharSequence target, CharSequence replacement) 是纯字面的匹配。replace方法中除了replaceFirst以外都是找出所有匹配的进行替换。
16. trim把比空格小的unicode都当成空白了:
public String trim() { int len = count; int st = 0; int off = offset; /* avoid getfield opcode */ char[] val = value; /* avoid getfield opcode */ while ((st < len) && (val[off + st] <= ' ')) { st++; } while ((st < len) && (val[off + len - 1] <= ' ')) { len--; } return ((st > 0) || (len < count)) ? substring(st, len) : this; }
17. intern 方法的注释很精确了:
Returns a canonical representation for the string object.
A pool of strings, initially empty, is maintained privately by the
class String
.
When the intern method is invoked, if the pool already contains a
string equal to this String
object as determined by
the equals(Object)
method, then the string from the pool is
returned. Otherwise, this String
object is added to the
pool and a reference to this String
object is returned.
It follows that for any two strings s
and t
,
s.intern() == t.intern()
is true
if and only if s.equals(t)
is true
.
All literal strings and string-valued constant expressions are interned.
17. 最后写了两个test case :
@Test public void testString() { String str = new String("ABC"); String str1 = new String("ABC"); assertFalse(str == str1); assertTrue(str.intern() == str1.intern()); assertEquals(str.length(), str.indexOf("", str.length())); assertEquals("ss", "\\w\\w".replace((CharSequence)"\\w", "s")); }
发表评论
-
读”Java 性能优化之 String 篇“有感
2013-01-20 00:33 3253读了 IBM Developer Works上的一篇 Ja ... -
读“熔岩”的"深入Java字符串" 有感
2013-01-19 23:52 1221读出熔岩同志的 深入Java字符串 ,感觉写得确实比较详尽, ... -
读 AbstractStringBuilder/StringBuilder/StringBuffer 源代码
2013-01-14 20:39 15821. StringBuilder和StringBuffer ... -
读 Character 原代码
2013-01-09 19:19 1805今天粗略读了一下Character的代码,总结如下: ... -
Unicode Character Representations In Java
2013-01-07 22:32 945Character information is based ... -
zz Unicode 详解
2013-01-07 17:04 1238本文转自 http://tech.idv2.com/2008/ ... -
Unicode Schema
2011-11-22 22:59 955Unicode was invented to o ... -
What is String literal pool?
2010-09-30 19:05 936What is String literal pool? ... -
Strings, Literally
2010-09-30 18:39 932The SCJP Tip LineStrings, Lit ...
相关推荐
源代码主要分布在`str.hpp`和`string_format.cpp`这两个文件中。 在`str.hpp`文件中,`format`函数可能被定义为一个模板函数,接受各种类型的参数,并将它们转换为字符串进行格式化。这个函数通常会利用`std::...
这个压缩包文件“jdk1.8”包含了Java 8的源代码,这对于开发者来说是一个宝贵的资源,可以深入理解其内部工作原理,帮助在实际项目中更高效地使用Java 8的功能。 首先,Java 8的最重要的新特性之一是Lambda表达式。...
文本编辑器源代码C代码 本资源是一个文本编辑器的源代码,使用C语言编写,包含了文本编辑器的基本功能,例如编辑、保存、加载、查找、替换等。下面是对该资源的详细解读: 标题:文本编辑器源代码 该标题表明了该...
**JSP目录直读程序源代码** 在Java Web开发中,JSP(JavaServer Pages)是一种用于创建动态网页的技术,它允许开发者将HTML代码与Java代码结合在一起,从而实现服务器端的数据处理和业务逻辑。本资源提供的“JSP...
《C#开发实战1200例源代码》是一个涵盖了大量C#编程实践案例的资源集合,对于初学者和有经验的开发者来说都是一个宝贵的参考资料。这个压缩包中包含的源代码实例覆盖了C#语言的各个核心概念,以及.NET框架的应用。...
本资源包含该书的源代码,旨在帮助读者更好地理解和实践书中的示例,提升编程技能。 在C#的学习过程中,源代码是至关重要的,它能让我们直观地看到程序的结构和工作方式。C#第6版引入了许多新的特性,如自动属性...
根据给定的信息,我们可以分析并总结出以下与文件读取及源代码相关的知识点: ### 1. 文件操作基础 在程序设计中,文件操作是非常重要的一个环节,它可以帮助我们保存数据到磁盘或者从磁盘读取数据。C++提供了多种...
代码有详细的解释 压缩包里面也有 数据库的文件 代码里设置的数据库 用户是 sa 密码是 123456 请使用的时候做相关的修改 下面给出 一部分的代码 请继续关注本资源的发布 会后面有很多实用的代码上传 using System....
在给定的`vehicleparam.c`和`vehicleparam.h`源代码文件中,我们可以预期它们实现了读取DBC文件的核心功能。以下是一些可能包含的关键函数和数据结构: 1. **数据结构定义**:首先,你需要定义表示DBC文件内容的...
在本教程中,我们将探讨如何在Visual C++ 6.0环境下编写C++源代码来实现文件读取。VC6.0是微软早期的一款集成开发环境(IDE),虽然现在已经有些过时,但它仍然是学习C++基础的好工具。 1. **打开文件**:在C++中,...
熟悉这些基本元素是读懂任何C语言源代码的前提。 2. **指针**:C语言中的指针是其强大之处,它们允许直接操作内存地址,实现高效的数据操作和动态内存管理。理解指针的声明、赋值、解引用以及指针与数组、函数的...
本压缩包包含了一个用C++语言编写的操作系统日志程序的源代码,这对于学习C++编程以及操作系统日志管理具有很高的价值。 在C++中编写操作系统日志程序,通常涉及以下几个关键知识点: 1. **文件I/O操作**:日志...
Message-Driven Bean EJB实例源代码 2个目标文件 摘要:Java源码,初学实例,EJB实例 Message-Driven Bean EJB实例源代码,演示一个接收购物订单的消息驱动Bean,处理这个订单同时通过e-mail的形式 //给客户发一个感谢...
在给定的"加密文件 C#源代码"主题中,我们可以深入探讨C#编程语言如何用于文件加密,特别是在Visual Studio 2005环境下。C#是一种面向对象的编程语言,由微软开发,广泛应用于构建Windows桌面应用、Web应用和服务。...
### 文件读写 Java 源代码知识点解析 #### 一、概述 在Java编程语言中,文件读写是一项基本而重要的功能。对于初学者来说,理解如何进行文件的输入输出操作至关重要。本篇文章将深入分析一段简单的Java源代码,该...
从加载过程我们可以看到,首先从Servlet事件中得到ServletContext,然后可以读到配置好的在web.xml的中的各个属性值,然后ContextLoder实例化WebApplicationContext并完成其载入和初始化作为根上下文。当这个根上...
1) 直接读源代码文件时 1. 根据扩展名适用不同的加亮规则 $stx = new STX(); echo $stx->stx_file($file); 2. 指定一个规则 $stx = new STX('perl'); echo $stx->stx_file($file); 2) 加亮字符串时: $stx...
《C#从入门到精通源代码2》是一个学习C#编程语言的重要资源,它包含了多个逐步进阶的示例和项目,旨在帮助初学者和有经验的开发者深化对C#的理解。C#是一种多范式、面向对象的编程语言,由微软开发并广泛应用于...
标题中的“汇编语言读寄存器内容的源代码”是指使用汇编语言编写的一段程序,该程序能够读取CPU寄存器的值,并将其转换为ASCII码形式存储或输出。描述中提到的环境是WINXP操作系统下,使用MASM5.0汇编器进行编译,...
这个压缩包"包含vb各种基本编程知识的例题及源代码",显然是一份丰富的学习资源,旨在帮助初学者理解和掌握VB编程的基础概念。通过实例和源代码,你可以亲手实践,从而更好地消化理论知识。 首先,VB的基本结构包括...