如何优化此方法以打破块中的字符串?

时间:2009-05-21 08:56:12

标签: java algorithm optimization string

这是方法。我想知道我是否违反了这里的任何最佳做法,或者就语言而言我做错了什么。

private List<String> breakStringInChunks(String text, int chunkSize) {
        List<String> chunks = new ArrayList<String>();
        String temporary = "";
        int numberOfChunks = text.length() / chunkSize;
        int beginIndex = 0;
        int endIndex = 0;

        // Add one iteration if numberOfChunks*chunkSize is less than the length of text.
        if ((numberOfChunks * chunkSize) < text.length()) {
            numberOfChunks++;
        }

        // Cut strings and add in the list.
        for (int i = 0; i < numberOfChunks; i++) {
            endIndex+=chunkSize;
            if ((i + 1) == numberOfChunks) {
                temporary = text.substring(beginIndex);
            }
            else {
                temporary = text.substring(beginIndex, endIndex);
            }
            beginIndex=endIndex;
            chunks.add(temporary);
        }

        return chunks;
    }

7 个答案:

答案 0 :(得分:4)

Briefer仍然,并避免可能调整结果列表的大小。

private static List<String> breakStringInChunks(final String text, final int chunkSize) {
    final int numChunks = 0 == (text.length() % chunkSize) ? text.length() / chunkSize : 1 + (text.length() / chunkSize);
    final List<String> chunks = new ArrayList<String>(numChunks);
    for (int startIndex = 0; startIndex < text.length(); startIndex += chunkSize) {
        final int endIndex = Math.min(text.length(), startIndex + chunkSize);
        chunks.add(text.substring(startIndex, endIndex));
    }
    return chunks;
}

答案 1 :(得分:1)

它有点冗长,并且不需要在方法的开头声明temporary字符串,这可能会使垃圾收集速度变慢。以下是更简洁的方法:

private List<String> breakStringInChunks(String text, int chunkSize) {
    int nChunks = (int)Math.ceil(((double)text.length())/chunkSize));
    List<String> chunks = new ArrayList<String>(nChunks);
    // Cut strings and add in the list.
    for (int i = 0; i < text.length(); i+=chunkSize) {
        int endIndex=i+chunksize;
        if (endIndex >= text.length()) {
            chunks.add(text.substring(i));
        } else {
            chunks.add(text.substring(i, endIndex));
        }
    }
    return chunks;
}

关于你的方法和上面的文本的一个好处是,因为你总是在原始String上调用substring(),所以Java只会引用原始字符数组,所以它会为你节省一些内存分配。

我认为} else {是Java的一种更常见的编码标准。

答案 2 :(得分:1)

除非我误解了你的意图,否则它似乎是一个巨大的矫枉过正,并且使用字符串创建很多次,使得算法在java中非常低效,因为字符串是不可变的。

试试这个:

public List<String> breakStringsInChunks(String text,int chunkSize) {
    if (chunkSize<=1) {
        throw new IllegalArgumentException("Chunk size must be positive");
    }
    if (text==null || text.isEmpty()) {
        return Collections.emptyList();
    }

    List<String> chunks= new LinkedList<String>();

    int index=0;
    int len = text.length();

    //guaranteed to succeed at least once since 0 length strings we're taken care of
    do {
        chunks.add(text.substring(index, Math.min(index + chunkSize, len)));
        index+=chunkSize;
    } while (index<len);

    return chunks;
}

答案 3 :(得分:0)

public static final List<String> chunk(final String text, final int chunkSize) {
    // Figure out how many chunks we are going to make.
    final int textLength = text.length();
    final int numberOfChunks =
        textLength % chunkSize == 0
        ? textLength / chunkSize
        : textLength / chunkSize + 1;

    // Create an array list of just the right size.
    final ArrayList<String> chunks = new ArrayList<String>(numberOfChunks);

    // Do all the chunking but the last one - here we know that all chunks
    // are exactly chunkSize long.
    for (int i = 0; i < numberOfChunks - 1; i++) {
        chunks.add(text.substring(i * chunkSize, (i + 1) * chunkSize));
    }

    // Add final chunk, which may be shorter than chunkSize, so we use textLength
    // as the end index.
    chunks.add(text.substring((numberOfChunks - 1) * chunkSize, textLength));

    return chunks;
}

答案 4 :(得分:0)

这是我的解决方案。我试图实现这个非常有效:

public static List<String> breakStringInChunks(String text, int chunkSize) {
    if (chunkSize < 2) {
        throw new IllegalArgumentException("Chunk size must be > 1");
    }
    if (null == text || text.isEmpty()) {
        return Collections.emptyList();
    }

    List<String> chunks = new ArrayList<String>(1 + (text.length() / chunkSize));

    int length = text.length() - (text.length() % chunkSize);

    for (int i = 0; i < length;) {
        chunks.add(text.substring(i, i += chunkSize));
    }
    if (length < text.length())
        chunks.add(text.substring(length));

    return chunks;
}

答案 5 :(得分:0)

这样的事情怎么样?

private List<String> breakStringInChunks(String text, int chunkSize)
{
    List<String> chunks = new ArrayList<String>();
    while (text.length() > 0)
    {
        if (chunkSize > text.length())
        {
            chunkSize = text.length();
        }
        chunks.add(text.substring(0, chunkSize));
        text = text.substring(chunkSize);
    }
    return chunks;
}

答案 6 :(得分:0)

这是我的。与其他一些答案没什么不同,但是测试驱动,fwiw。

public class ChunkTest extends TestCase {
    public void testEmpty() throws Exception {
        assertEquals(0, breakStringInChunks("", 1).size());
    }

    public void testOneChunk() throws Exception {
        String s = "abc";
        List<String> chunks = breakStringInChunks(s, s.length());
        assertEquals(s, chunks.get(0));
        assertEquals(1, chunks.size());
    }

    public void testPartialChunk() throws Exception {
        String s = "abc";
        List<String> chunks = breakStringInChunks(s, s.length() + 1);
        assertEquals(s, chunks.get(0));
        assertEquals(1, chunks.size());
    }

    public void testTwoChunks() throws Exception {
        String s = "abc";
        List<String> chunks = breakStringInChunks(s, 2);
        assertEquals("ab", chunks.get(0));
        assertEquals("c", chunks.get(1));
        assertEquals(2, chunks.size());
    }

    public void testTwoEvenChunks() throws Exception {
        String s = "abcd";
        List<String> chunks = breakStringInChunks(s, 2);
        assertEquals("ab", chunks.get(0));
        assertEquals("cd", chunks.get(1));
    }

    private List<String> breakStringInChunks(String text, int chunkSize) {
        if (text.isEmpty())
            return Collections.emptyList();
        int n = (text.length() + chunkSize - 1) / chunkSize;
        List<String> chunks = new ArrayList<String>(n);
        for (int i = 0; i < n; ++i)
            chunks.add(text.substring(i * chunkSize, Math.min((i + 1) * chunkSize, text.length())));
        return chunks;
    }
}