Android / Java从int转换为String而不分配?

时间:2011-07-04 04:15:07

标签: java android math integer tostring

考虑过我在为Android创建的其中一个应用程序中不得不重复从int转换为String。我坐下来写了一个小实用程序类,我认为这样可以减轻由于Integer.toString()等函数调用而无法看到的潜伏变量的分配......

private int[] iMods = {
        1,
        10,
        100,
        1000,
        10000,
        100000,
        1000000,
        10000000,
        100000000,
        1000000000};

private int tmpInt = 0;
private int MAX_DIGITS = 6;
private char[] cScoreDigit = new char[MAX_DIGITS];
private int[] iScoreDigit = new int[MAX_DIGITS];
private StringBuilder mScoreStringBuilder = new StringBuilder("000000");


public String intToString(final int pInt, final int pMAX_DIGITS){
    MAX_DIGITS = pMAX_DIGITS;

    for (tmpInt = 1; tmpInt <= MAX_DIGITS; tmpInt++){   // Set each cScoreDigit to proper equivalent of iScoreDigit without cast!
        switch ((pInt % iMods[tmpInt]) / iMods[tmpInt - 1]){
        case 0:
            cScoreDigit[MAX_DIGITS - tmpInt] = '0';
            break;
        case 1:
            cScoreDigit[MAX_DIGITS - tmpInt] = '1';
            break;
        case 2:
            cScoreDigit[MAX_DIGITS - tmpInt] = '2';
            break;
        case 3:
            cScoreDigit[MAX_DIGITS - tmpInt] = '3';
            break;
        case 4:
            cScoreDigit[MAX_DIGITS - tmpInt] = '4';
            break;
        case 5:
            cScoreDigit[MAX_DIGITS - tmpInt] = '5';
            break;
        case 6:
            cScoreDigit[MAX_DIGITS - tmpInt] = '6';
            break;
        case 7:
            cScoreDigit[MAX_DIGITS - tmpInt] = '7';
            break;
        case 8:
            cScoreDigit[MAX_DIGITS - tmpInt] = '8';
            break;
        case 9:
            cScoreDigit[MAX_DIGITS - tmpInt] = '9';
        }       
    }

    // Delete all 0's
    mScoreStringBuilder.delete(0, mScoreStringBuilder.length());
    return mScoreStringBuilder.append(cScoreDigit).toString();
}

现在我只是好奇A)这是否真的是这样做的正确方法,以及B)这样的事情是否值得研究,因为每一步都有额外的数学运算?似乎反效果,但至少会限制GC运行正确吗?提前谢谢!

[编辑]

我注意到StringBuilder.toString()实际上会分配一个临时对象,这正是我试图避免的。没有分配的任何其他方式简单地从char []转换为String?或者如下所述,这对于String类是不可能的?

1 个答案:

答案 0 :(得分:2)

不,最后的toString创建一个新的String(如果你愿意,请检查代码,java库源都可用)。

由于字符串是不可变的,因此您无法避免分配,因为您返回了一个字符串。

如果您返回用于构建数字的字符串构建器,并在下次调用时重复使用它,并且永远不会将其转换为字符串,您可以正常使用,但第二次将其转换为字符串(无论如何)你是怎么做的)你正在分配内存。

要做到这一点,你的方法要么必须接受传入的可变对象(StringBuilder或char数组),要么必须重用静态对象(使其成为单线程)

我尝试了一次,它总是归结为在某种程度上将它转换为字符串,取消所有工作,并使它比你刚刚使用显而易见的方式更慢。

还要记住,在Java中,短期内存分配并不像你想象的那么糟糕 - 它们在性能方面更像是C中的堆栈分配。

我所做的研究和测试表明,你可以做的一件事是避免在循环中连接字符串 - 其他一切(包括一次性字符串连接)最简单的代码将比你能做的任何事情都快或快想出来。