申明:转载请注明出处,如有商用目的请务必知会本人,感谢。

上一篇文章:http://blog.csdn.net/ts1122/article/details/8738336,介绍了String一些易错内容。这里接着大体介绍下String类提供的API。大体就是不对API做一一介绍,只是根据类型说个大概,再选择一些经典的方法详细说明下。说明下,这两篇文章都是基于JDK1.7.0_17版本进行说明的,本文章后面的内容会说到JDK1.7版本String类的实现和JDK1.6版本还是很大不同的。
        先说构造方法,String类里面构造方法很多。由于方法签名只与方法名称以及参数类型有关系,这么多构造方法的差异就只能是传递的参数类型和数目。不过有的构造方法基本不会被用到,比如下面两个:

  1. public String() {
  2. this.value = new char[0];
  3. }
  4. public String(String original) {
  5. this.value = original.value;
  6. this.hash = original.hash;
  7. }

第一个构造方法之所以不用,说明文档里面写的很清楚:由于String是不可变的,当前方法的基本没用。这个方法给出了一个指向空字符串的引用,之后指向的内容又不能改变,所以没有什么用处。Java里面有些类叫做不可变类,其定义为:类中的每个方法都不能改变其对象。一般这种类中的数据域都有加final修饰,String类就是一个不可变类,其数据域就加了final字符修饰。上面的第二个方法之所以不用是因为会多分配一块内存,JVM会在当前线程的stringpool中分配一块内存,之后在堆中再分配一块内存。构造一个String,我们一般只要用String = “abc”这种方式就足够了,而且简单高效,这种用法也是java推荐的。:-D
        下面是一组和String类数据域有关的方法:

  1. public int length()
  2. public boolean isEmpty()
  3. public char charAt(int index)
  4. public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin)

这三个方法都是基于String的数据域char value[]实现的,比如返回value.length。这些方法经常有用到,得记住。最后一个方法是将String中数据域内容拷贝到char数组方法,用System.arraycopy的本地方法实现,效率应该很高。
        接下来是一组String内容比较方法:

  1. public boolean equals(Object anObject)
  2. public boolean equalsIgnoreCase(String anotherString)
  3. public boolean contentEquals(CharSequence cs)
  4. public int compareTo(String anotherString)

第一个方法比较两个字符串对象内容是否完全相等,如果是就返回true。第二个方法从方法名称就可以理解,不考虑大小写进行比较。看了下第二个方法的内部实现,先把字符统一转成大写进行比较,如果不行再转成小写进行比较,看说明文档对于Georgian alphabet就有这种大写不成要用小写的特殊情况。:-(   第三个方法和前面两个方法基本一样,只不过参数类型不同。最后一个方法和C语言中的一样:取两个字符串较短的长度,从第一个字符开始对两个字符串进行比较,如果出现第一个不同的字符则返回两个字符之间的差值。结果返回是0的话就说明两个字符串内容相等。但是这个方法在java中很少用到。
        一组新的字符串内容比较方法:

  1. public int indexOf(int ch)
  2. public int indexOf(int ch, int fromIndex)
  3. public int lastIndexOf(int ch)
  4. public boolean startsWith(String prefix)
  5. public boolean startsWith(String prefix, int toffset)
  6. public boolean endsWith(String suffix)
  7. public int indexOf(String str)
  8. public int indexOf(String str, int fromIndex)
  9. public int lastIndexOf(String str)

前面三个方法都是返回一个字符在当前字符串中的位置。后面一组方法是寻找一组字符串在当前字符串中的位置,和前面一组方法很相似。
        一组易被忽视会产生新的字符串对象的方法:

  1. public String substring(int beginIndex)
  2. public String substring(int beginIndex, int endIndex)
  3. public String replace(char oldChar, char newChar)
  4. public String toLowerCase()
  5. public String toUpperCase()
  6. public String trim()

这些都是对当前字符串内容进行截取,替换,大小写变更等操作的方法。由于String类是不可变类,这些方法不能改变对象内容,只能新分配内存保存操作结果,如果滥用这些方法会造成内存泄露的。
        这里根据public String substring(int beginIndex)说一下JDK1.6和JDK1.7String类的一些不同。JDK1.6上String类的数据域如下:

  1. /** The value is used for character storage. */
  2. private final char value[];
  3. /** The offset is the first index of the storage that is used. */
  4. private final int offset;
  5. /** The count is the number of characters in the String. */
  6. private final int count;

即其包含一个类似高中几何上向量的东西,给出内容同时还给出了一个起始点和长度的游标。JDK1.6中在实现substring最终会用到下面的方法:

  1. // Package private constructor which shares value array for speed.
  2. String(int offset, int count, char value[]) {
  3. this.value = value;
  4. this.offset = offset;
  5. this.count = count;
  6. }

这就是说截取一段某一个字符串中的一段,实际上并没有分配新的内存,只是提供了一个新的向量,返回的引用仍然指向原来的字符串。如果原来的字符串不再使用,仅使用新的截取的字符串,个人认为就造成内存浪费。如果每次都是从一个很长很长字符串中截取一小段内容,就造成了内存的极大浪费,这也是JDK1.6使用过程中,关于字符串的一个优化点。再看JDK1.7中String类就只有char value[]一个数据域,方法substring就采取了新的做法,如下:

  1. this.value = Arrays.copyOfRange(value, offset, offset+count);

这句代码完成这个方法实现主体,分配了新的内存,将需要的内容拷贝到新的内存中。看JDK文档中说明,1.6的这种做法是为了速度。:-D
       接下来就是valueOf方法,都是像    public static String valueOf(Object obj) 这样的类方法,这些方法的实现其实就是参数本身的toString方法的实现。最后就是split方法,这个涉及到了正则表达式,这里暂不介绍。:-D

版权声明:本文为博主原创文章,未经博主允许不得转载。

java 基于JDK中的源码总结下String二的更多相关文章

  1. Java基础-集合框架-ArrayList源码分析

    一.JDK中ArrayList是如何实现的 1.先看下ArrayList从上而下的层次图: 说明: 从图中可以看出,ArrayList只是最下层的实现类,集合的规则和扩展都是AbstractList. ...

  2. Java并发工具类CountDownLatch源码中的例子

    Java并发工具类CountDownLatch源码中的例子 实例一 原文描述 /** * <p><b>Sample usage:</b> Here is a pai ...

  3. JDK源码阅读-------自学笔记(一)(java.lang.Object重写toString源码)

    一.前景提要 Object类中定义有public String toString()方法,其返回值是 String 类型. 二.默认返回组成 类名+@+16进制的hashcode,当使用打印方法打印的 ...

  4. Java并发系列[5]----ReentrantLock源码分析

    在Java5.0之前,协调对共享对象的访问可以使用的机制只有synchronized和volatile.我们知道synchronized关键字实现了内置锁,而volatile关键字保证了多线程的内存可 ...

  5. 观察者模式—jdk自带源码分析

    一:观察者模式简介 二:jdk实现观察者模式的源码 三:实际例子 四:观察者模式的优点和不足 五:总结 一:观察者模式简介 有时又被称为发布(publish )-订阅(Subscribe)模式.模型- ...

  6. java集合系列之ArrayList源码分析

    java集合系列之ArrayList源码分析(基于jdk1.8) ArrayList简介 ArrayList时List接口的一个非常重要的实现子类,它的底层是通过动态数组实现的,因此它具备查询速度快, ...

  7. JDK容器类Map源码解读

    java.util.Map接口是JDK1.2开始提供的一个基于键值对的散列表接口,其设计的初衷是为了替换JDK1.0中的java.util.Dictionary抽象类.Dictionary是JDK最初 ...

  8. 基于Eclipse搭建Hadoop源码环境

    Hadoop使用ant+ivy组织工程,无法直接导入Eclipse中.本文将介绍如何基于Eclipse搭建Hadoop源码环境. 准备工作 本文使用的操作系统为CentOS.需要的软件版本:hadoo ...

  9. Java集合系列[4]----LinkedHashMap源码分析

    这篇文章我们开始分析LinkedHashMap的源码,LinkedHashMap继承了HashMap,也就是说LinkedHashMap是在HashMap的基础上扩展而来的,因此在看LinkedHas ...

随机推荐

  1. IT第八天 - 类的应用、debug、项目开发模式优化

    IT第八天 上午 类的应用 1.对象在实例化时是非常耗费系统资源的,因此要尽量减少new字段的使用 2.类的初始值是null,在使用未实例化的类时,很容易导致报错:NullExceptionPoint ...

  2. BZOJ 1726: [Usaco2006 Nov]Roadblocks第二短路

    1726: [Usaco2006 Nov]Roadblocks第二短路 Description 贝茜把家搬到了一个小农场,但她常常回到FJ的农场去拜访她的朋友.贝茜很喜欢路边的风景,不想那么快地结束她 ...

  3. [Oracle] 11G自己主动收集统计信息

    在11g中,默认自己主动收集统计信息的时间为晚上10点(周一到周五,4个小时),早上6点(周六,周日,20个小时),例如以下所看到的: select a.window_name, a.repeat_i ...

  4. String详解说明

    大家平时都string都不是很在意,但是每当面试碰到String的时候在“==”和equals之间就乱了,下面我来说一说String,也许不够全面,请大家多多指教,希望会帮到处于蒙圈状态的人们. 一. ...

  5. ContentProvider中的数据库的生成时机以及ContentResolver的insert()方法总结

    经过几天的总结,以及结合一些代码的实际测试,终于算是明白了ContentProvider中的数据的生成时机了. 目录结构: MainActivity.java package com.wyl.cont ...

  6. iOS字符串NSString中去掉空格(或替换为某个字符串)

    http://blog.sina.com.cn/s/blog_6f29e81f0101qwbk.html [问题描述]       今天请求服务器返回的字段中含有空格,这空格是服务器开发人员不小心往数 ...

  7. 花海漫步 NOI模拟题

    题目好像难以看懂? 题目大意 给出一个字符串\(S\),统计满足以下条件的\((i,j,p,q)\)的数量. \(i \leq j, p \leq q\) \(S[i..j],S[p..q]\)是回文 ...

  8. vim-ctags-taglist-netrw

    vim配置 在~/.vimrc文件里配置例如以下内容.或者在/etc/vim/vimrc中进行全局配置,经常使用配置例如以下: syntax on set tabstop=4 set nu set s ...

  9. 【C语言】数字在排序数组中出现的次数(改动)

    //数字在排序数组中出现的次数(改动) //统计一个数字在排序数组中出现的次数.比如:排序数组{1,2,3,3,3.3,4,5}和数字3,因为3出现了4次,因此输出4. #include <st ...

  10. C++ 函数声明中指定,默认参数

    C++ 在声明函数的时候,如果指定了,参数的默认值,再调用函数的时候可以省略后面的参数. 如果调用函数写上的参数,但是不全.参数列表后面的使用默认值.如下例子,一看就清楚了. #include < ...