私は、文字列#のsubstringメソッドを誤解しました

免責事項:この記事はブロガーオリジナル記事です、続くBY-SAのCC 4.0を著作権契約、複製、元のソースのリンクと、この文を添付してください。
このリンク: https://blog.csdn.net/lidelin10/article/details/102764626

私たちは、一般的に、パターンマッチング、我々はマッチ開始と終了を取得する場合には特に、その後、呼び出し、サブ文字列を傍受操作を使用してstr.substring(start, end)エンド)の範囲、開始[サブストリング傍受を。次のように最近、私は敏感なワードフィルタリングに事業を行ってきた、私は前方最長の文字列照合文字列が辞書に存在して取得したいと思い、それから、コードの一部は、減感作治療であります:

public CharSequence searchNextMatch(String sourceText, int start, int end) {
    TireTreeFindResult findResult = tireTree.find(sourceText, start, end);//获取匹配的结果,结果会包含匹配的起始下标和结束下标(exclude)
    return sourceText.substring(findResult.getMatchTextStart(), findResult.getMatchTextEnd());
}

私は、これはあまり問題ではありません、文字列の部分文字列メソッドは文字列の結果を返します。その時、ソースコードのサブを見て、彼は方法最初のchar配列をサブストリングによってコピーされ、その後、char型の配列を使用してStringオブジェクトを再作成することが判明し、私はいつも、サブストリングは、サブリストビューのような文字列を返すことを考えているが、そうではありませんそう。このようにそれを実現するために遅くなることはないだろう。だから、いくつかの問題を抱えていましたか?なぜ達成するために、このJava APIを選ぶのか?

私は少しの部分文字列を検索し、オンラインに行くと、彼女はいくつかの手がかりを見つけました。JDK7の前にサブストリングがビューを通じて達成が、JDK7に、その配列に変更し、文字のコピーを作成しています。新たに改訂され、効率が比較的低いことは明らかであるが、この変更は、特定の考慮事項です。

私たちは爬虫類1つのページのHTMLソースhtmlStringによって取得する場合は、一致と部分文字列は、正を通じて満足のいく試合を取得List<String>List<String>文字列の列のポイントですべてがあるhtmlString.value、我々はあなたが必要な情報を取得した後、破棄しなければなりませんhtmlStringJVMが失われた回復、しかしので聞かせてList<String>、すべての要素がで参照されているhtmlString.value、それはメモリリークが発生する場所ラージ・オブジェクト・ストリングにつながるが、リサイクルすることができません。

時には、効率の関心は、私たちは自分自身で、ビューのCharSequenceクラスを達成することができ、次のように、コードは次のとおりです。

/**
* 使用视图减少substring的开销
*/
private static class SubstringView implements CharSequence{
    private String sourceString;
    private int start;
    private int end;
    private int length;


    public SubstringView(String sourceString, int start, int end) {
        checkBounds(sourceString, start, end);
        this.sourceString = sourceString;
        this.start = start;
        this.end = end;
        this.length = end - start;
    }


    @Override
    public int length() {
        return this.length;
    }


    @Override
    public char charAt(int index) {
        if (start + index > end){
            throw new IndexOutOfBoundsException(String.valueOf(index));
        }
        return sourceString.charAt(start + index);
    }


    @Override
    public CharSequence subSequence(int start, int end) {
        return new SubstringView(sourceString, start, end);
    }


    private void checkBounds(String string, int start, int end){
        if (start > end){
            throw new IllegalArgumentException("start > end");
        }


        if (end > string.length()){
            throw new IllegalArgumentException("end is greater than source string length");
        }
    }
}

これは、APIを提供しながら、パラメータとして文字列のCharSequenceに留意すべきであるが、内部はちょうどtoStringメソッドを呼び出すことができ、およびのための同じ一般的なカテゴリのtoStringのデフォルトの実装で、CharSequence引数のクラスを達成するために:完全なクラス名@hashCode

String str1 = "1234abc111";
String str2 = "abc";
CharSequence sequence = new SubstringView(str1, 4, 4 + 3);
System.out.println(str2.contains(sequence));

このサンプル出力が偽で、その理由は、判決の内部ロジックが含まれていますindexOf(s.toString()) > -1、呼び出しSubstringView#toString当方は一切実装されていないのtoString、。次に、どのように我々はtoStringメソッドを達成していますか?この方法は、唯一のtoString呼び出すことができます実現するためにString#substring他の方法ではない方法。

参考:

  1. このブログは、ブロガー比較の視点からの多重化、セキュリティ、古い新しい実装の配列を解析するために、詳細にそれを説明し、以下を参照してください。https://www.cnblogs.com/antineutrino/p/4213268.html

  2. java.lang.String#substringソース

  3. java.lang.StringBuilder#substringソース

おすすめ

転載: blog.csdn.net/lidelin10/article/details/102764626