首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java:避免使用自定义类创建新字符串的StringBuilder.toString()

Java:避免使用自定义类创建新字符串的StringBuilder.toString()
EN

Stack Overflow用户
提问于 2014-01-22 10:55:29
回答 2查看 677关注 0票数 2

在一个Android游戏中,我有一个循环,运行大约1500万次,在这个循环中,我会修改单词片段,并在字典中检查结果。我注意到很多GC调用,我的主要怀疑是StringBuilder.toString(),它总是创建一个新的字符串。

我在Java方面比较有经验,不知道如何避免这种分配,并以某种方式将内部char数组传递给包含(),而不需要任何分配或复制。

描述我的问题的简化伪代码片段:

代码语言:javascript
复制
static HashSet<String>dictionary;       // loaded from text file
String[7] wordParts = new String[7];    // pre-filled from player data
StringBuilder sb = new StringBuilder(20);

for (i=15 million times) {
    sb.setLength(0);
    for (j=2-7 times) {
       sb.append(wordParts[j]);
    }
    if (dictionary.contains(sb.toString()) {
        processValidWord();
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-01-23 13:26:59

使用Pablo的建议:

代码语言:javascript
复制
static HashSet<DictionaryItem>dictionary;       // loaded from text file
String[7] wordParts = new String[7];            // pre-filled from player data
DictionaryItem di = new DictionaryItem();

for (i=15 million times) {
   di.setEmpty();
   for (j=2-7 times) {
      di.append(wordParts[j]);
   }
   if (dictionary.contains(di) {
       processValidWord();
   }
}

从字符串和StringBuilder中窃取,但是为这个特殊的应用程序动态构建哈希代码:

代码语言:javascript
复制
public class DictionaryItem {
    int hashCode;
    int length;
    char[] chars = new char[15];

    public DictionaryItem(String initialValue) {
        this();
        append(initialValue);
    }

    public DictionaryItem() {
        setEmpty();
    }

    public void setEmpty() {
        hashCode = 0;
        length = 0;
    }

    public void append(String s) {
        for (int i=0;i<s.length();i++) {
            chars[length++] = s.charAt(i);
            hashCode = 31*hashCode + s.charAt(i);
        }
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o instanceof DictionaryItem) {
            DictionaryItem di = (DictionaryItem)o;
            if (di.length == length) {
                int i = length-1;
                while (i >= 0) {
                    if (di.chars[i] != chars[i]) {
                        return false;
                    }
                    i--;
                }
                return true;
            }
        }
        return false;
    }

    @Override
    public int hashCode() {
        return hashCode;
    }

    @Override
    public String toString() {
        return new String(chars, 0, length);
    }
}

现在搜索期间没有分配,toString()很少用于向用户显示结果。

票数 0
EN

Stack Overflow用户

发布于 2014-01-22 10:57:38

据我所知,在Java7中,它们更改了String类的内部实现,删除了要在不同string之间共享的char[] (偏移量值指示该字符串中的第一个字符和该字符串的长度)。

检查这里,06/

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21280925

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档