java String.subString用法

转载 2015年07月09日 19:31:12

原文地址:http://www.cnblogs.com/tedzhao/archive/2012/07/31/Java_String_substring.html


Java中的substring函数是我们经常使用的一个函数,用来截取当前字符串的子串,定义如下:


public final class String{
    public String substring(int beginIndex);
    public String substring(int beginIndex, int endIndex);
}

使用及声明都非常简单,但是你了解其中的细节吗?

我们再看一下substring的实现:

public String substring(int beginIndex, int endIndex) {
        if (beginIndex < 0) {
            throw new StringIndexOutOfBoundsException(beginIndex);
        }
        if (endIndex > count) {
            throw new StringIndexOutOfBoundsException(endIndex);
        }
        if (beginIndex > endIndex) {
            throw new StringIndexOutOfBoundsException(endIndex - beginIndex);
        }
        return ((beginIndex == 0) && (endIndex == count)) ? this :
            new String(offset + beginIndex, endIndex - beginIndex, value);
}


在第12行返回了一个新的字符串,传入了三个参数:offset,count,以及原来String对象的value(char[])。

继续看第12行String的构造函数:


String(int offset, int count, char value[]) {
        this.value = value;
        this.offset = offset;
        this.count = count;
}

这是一个Package内部的方法,非public,注意他直接将传入的char[]给抓住了,定义了起始位置,以及长度。

我理解他设计的初衷是为了节省内存,新的字符串还依然抓着老的字符串value的引用,只是重新定义起始位置和长度

再补充一下String类的字段声明,可以看得更清楚一点:

public final class String{
   /** The value is used for character storage. */
    private final char value[];


    /** The offset is the first index of the storage that is used. */
    private final int offset;


    /** The count is the number of characters in the String. */
    private final int count;


    /** Cache the hash code for the string */
    private int hash; // Default to 0

华丽的分割线下是我的使用场景:

逐行读取一个非常大的文本文件,每一行的长度比较大,提取其中的小部分(使用了substring函数),大约每行提取10个字,行数很多(整个文本可能会有几十M或更多)。

读取文件完毕后我理解的内存消耗不会很大,但是完全出乎我的想象,内存消耗很大,甚至会outofmemory.


List<String> results = new ArrayList<String>();
InputStream stream = new FileInputStream(filePath);
BufferedReader bufferredReader = new BufferedReader(
                new InputStreamReader(stream));
while (true) {
    String line = bufferredReader.readLine();
    if (line == null) {
                break;
    }


    results.add(line.substring(10, 20));
}


Why?在查看了String的substring函数以及多方Google之后,终于明白了。

原来新构建的String依然抓着每一行的文本,只是调整了offset和length,不是我们所理解的只抓着一个小文本,原来的长文本被GC回收这么回事。

怎么办呐?只需要改一句:


构建一个新的String,将字串传入,这样与原始字符串就没有关系了。所以在使用substring的时候,必须要注意使用场景。

最后再提醒一个,String的split函数返回的子串也是如此。

 



List<String> results = new ArrayList<String>();
InputStream stream = new FileInputStream(filePath);
BufferedReader bufferredReader = new BufferedReader(
                new InputStreamReader(stream));
while (true) {
    String line = bufferredReader.readLine();
    if (line == null) {
                break;
    }

    results.add(new String(line.substring(10, 20)));
}

按 Ctrl

string里的IndexOf、LastIndexOf、Substring的详解(意义和用法)

今天遇到截取字符串的问题,在网上查了IndexOf、LastIndexOf、Substring这三种截取字符串的使用总结如下:     String.IndexOf   String...

Java -- String类substring方法

虽然JDK8已推出有些日子了,但此仍是

java慎用String.substring(int start, int end)

1:问题的抛出         今天在安卓项目中使用后台线程操作一个大文件,分块读取文件中的所有内容,每次操作加载一个小块进行解析,解析到指定的文本内容之后会加载并常驻内存中,即使所有我解析到的文本内...

java.lang.String的substring、split方法引起的内存问题

本文大部分内容,摘自下面两篇文章:            http://blog.xebia.com/2007/10/04/leaking-memory-in-java/、            ...

java---------------String类的截取字符串,截串,substring和split,分割字母和数字,正则缝隙

java 截取字符串,截串,substring和split,分割字母和数字,正则缝隙 博客分类:  java Java正则表达式  需求,把"01:大汽车",...
  • sno_guo
  • sno_guo
  • 2013年09月26日 08:24
  • 2605

你了解Java中String的substring函数吗?

Java中的substring函数是我们经常使用的一个函数,用来截取当前字符串的子串,定义如下: public final class String{ public String sub...
  • yuanyl
  • yuanyl
  • 2014年10月22日 15:47
  • 248

Is the Improvement of String.substring() in Java7 Really Reasonable?

String#substring()在Java6和Java7中的实现是不一样的。这是因为Java6的实现可能导致内存问题,所以Java7中为了改善这个问题修改了实现方式。那么Java7中的实现就真的合...

public String substring(int beginIndex, int endIndex)(Java)

基础不牢,地动山摇。今天开始写一些基础Java卷子,写这篇博文原因是看到了这个题。然后抱着认真学习的态度,默默地去敲了一下代码。确实使这个结果: 函数的源代码是这样的:/** * Retu...

【Java】JDK6和JDK7中String的substring()方法及其差异

翻译人员: 铁锚 翻译日期: 2013年11月2日 原文链接: The substring() Method in JDK 6 and JDK 7    在JDK6与JDK7这两个版本中,subst...

JAVA中subString以及split函数等几个函数的用法技巧

一、先说一说subString()函数        subString函数有个陷阱,有可能导致内存泄露(当然,在JDK1.7.0-B147之前这个问题一直存在,在JDK1.7.0_15-b03版本...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:java String.subString用法
举报原因:
原因补充:

(最多只允许输入30个字)